blob: 253a19f660c391c029477602853150b1f2783892 [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;
Jeff Sharkey64c96ec2017-08-30 16:28:26 -060041import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
Jeff Sharkey9252b342018-01-19 07:58:35 +090042import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
Jeff Sharkey22c055e2011-06-12 21:13:51 -070043import static android.net.NetworkPolicy.LIMIT_DISABLED;
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -070044import static android.net.NetworkPolicy.SNOOZE_NEVER;
Jeff Sharkey497e4432011-06-14 17:27:29 -070045import static android.net.NetworkPolicy.WARNING_DISABLED;
Jeff Sharkey14711eb2011-06-15 10:29:17 -070046import static android.net.NetworkPolicyManager.EXTRA_NETWORK_TEMPLATE;
Xiaohui Chenb41c9f72015-06-17 15:55:37 -070047import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_DOZABLE;
Felipe Leme011b98f2016-02-10 17:28:31 -080048import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_POWERSAVE;
Xiaohui Chenb41c9f72015-06-17 15:55:37 -070049import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_STANDBY;
50import static android.net.NetworkPolicyManager.FIREWALL_RULE_ALLOW;
Jeff Sharkeydc988062015-09-14 10:09:47 -070051import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT;
Amith Yamasani15e472352015-04-24 19:06:07 -070052import static android.net.NetworkPolicyManager.FIREWALL_RULE_DENY;
Jeff Sharkey43d2a172017-07-12 10:50:42 -060053import static android.net.NetworkPolicyManager.MASK_ALL_NETWORKS;
54import static android.net.NetworkPolicyManager.MASK_METERED_NETWORKS;
Felipe Leme46b451f2016-08-19 08:46:17 -070055import static android.net.NetworkPolicyManager.POLICY_ALLOW_METERED_BACKGROUND;
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -070056import static android.net.NetworkPolicyManager.POLICY_NONE;
Jeff Sharkeyfdfef572011-06-16 15:07:48 -070057import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND;
Felipe Lemed31a97f2016-05-06 14:53:50 -070058import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL;
Felipe Leme70c57c22016-03-29 10:45:13 -070059import static android.net.NetworkPolicyManager.RULE_ALLOW_METERED;
Felipe Leme46c4fc32016-05-04 09:21:43 -070060import static android.net.NetworkPolicyManager.RULE_NONE;
Felipe Lemed31a97f2016-05-06 14:53:50 -070061import static android.net.NetworkPolicyManager.RULE_REJECT_ALL;
Jeff Sharkeyfdfef572011-06-16 15:07:48 -070062import static android.net.NetworkPolicyManager.RULE_REJECT_METERED;
Felipe Leme70c57c22016-03-29 10:45:13 -070063import static android.net.NetworkPolicyManager.RULE_TEMPORARY_ALLOW_METERED;
Sudheer Shankae359c3d2017-02-22 18:41:29 -080064import static android.net.NetworkPolicyManager.isProcStateAllowedWhileIdleOrPowerSaveMode;
65import static android.net.NetworkPolicyManager.isProcStateAllowedWhileOnRestrictBackground;
Jeff Sharkey43d2a172017-07-12 10:50:42 -060066import static android.net.NetworkPolicyManager.resolveNetworkId;
Felipe Lemeb146f762016-08-19 09:52:16 -070067import static android.net.NetworkPolicyManager.uidPoliciesToString;
Felipe Leme46c4fc32016-05-04 09:21:43 -070068import static android.net.NetworkPolicyManager.uidRulesToString;
Jeff Sharkeye0c29952018-02-20 17:24:55 -070069import static android.net.NetworkTemplate.MATCH_MOBILE;
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -070070import static android.net.NetworkTemplate.MATCH_WIFI;
Jeff Sharkey4e814c32011-07-14 20:37:37 -070071import static android.net.NetworkTemplate.buildTemplateMobileAll;
Jeff Sharkey241dde22012-02-03 14:50:07 -080072import static android.net.TrafficStats.MB_IN_BYTES;
Jeff Sharkey36b414b2018-03-30 11:00:03 -060073import static android.provider.Settings.Global.NETPOLICY_OVERRIDE_ENABLED;
74import static android.provider.Settings.Global.NETPOLICY_QUOTA_ENABLED;
75import static android.provider.Settings.Global.NETPOLICY_QUOTA_FRAC_JOBS;
76import static android.provider.Settings.Global.NETPOLICY_QUOTA_FRAC_MULTIPATH;
77import static android.provider.Settings.Global.NETPOLICY_QUOTA_LIMITED;
78import static android.provider.Settings.Global.NETPOLICY_QUOTA_UNLIMITED;
Ammar Aijazi6ce48e22017-03-28 15:43:22 -070079import static android.telephony.CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED;
Ammar Aijazi6ce48e22017-03-28 15:43:22 -070080import static android.telephony.CarrierConfigManager.DATA_CYCLE_THRESHOLD_DISABLED;
Jeff Sharkey43d2a172017-07-12 10:50:42 -060081import static android.telephony.CarrierConfigManager.DATA_CYCLE_USE_PLATFORM_DEFAULT;
Jeff Sharkey9252b342018-01-19 07:58:35 +090082import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
Felipe Leme03e689d2016-03-02 16:17:38 -080083
Jeff Sharkey854b2b12012-04-13 16:03:40 -070084import static com.android.internal.util.ArrayUtils.appendInt;
Jeff Sharkey21c9c452011-06-07 12:26:43 -070085import static com.android.internal.util.Preconditions.checkNotNull;
Jeff Sharkeyded7b752013-03-22 13:43:41 -070086import static com.android.internal.util.XmlUtils.readBooleanAttribute;
87import static com.android.internal.util.XmlUtils.readIntAttribute;
88import static com.android.internal.util.XmlUtils.readLongAttribute;
Jeff Sharkey17bebd22017-07-19 21:00:38 -060089import static com.android.internal.util.XmlUtils.readStringAttribute;
Jeff Sharkeyded7b752013-03-22 13:43:41 -070090import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
91import static com.android.internal.util.XmlUtils.writeIntAttribute;
92import static com.android.internal.util.XmlUtils.writeLongAttribute;
Jeff Sharkey17bebd22017-07-19 21:00:38 -060093import static com.android.internal.util.XmlUtils.writeStringAttribute;
Jeff Sharkey961e3042011-08-29 16:02:57 -070094import static com.android.server.NetworkManagementService.LIMIT_GLOBAL_ALERT;
Sudheer Shanka352dc572017-09-22 17:09:38 -070095import static com.android.server.net.NetworkPolicyLogger.NTWK_ALLOWED_DEFAULT;
96import static com.android.server.net.NetworkPolicyLogger.NTWK_ALLOWED_NON_METERED;
97import static com.android.server.net.NetworkPolicyLogger.NTWK_ALLOWED_TMP_WHITELIST;
98import static com.android.server.net.NetworkPolicyLogger.NTWK_ALLOWED_WHITELIST;
99import static com.android.server.net.NetworkPolicyLogger.NTWK_BLOCKED_BG_RESTRICT;
100import static com.android.server.net.NetworkPolicyLogger.NTWK_BLOCKED_BLACKLIST;
101import static com.android.server.net.NetworkPolicyLogger.NTWK_BLOCKED_POWER;
Jeff Sharkey497e4432011-06-14 17:27:29 -0700102import static com.android.server.net.NetworkStatsService.ACTION_NETWORK_STATS_UPDATED;
Jeff Sharkey7474fe7b2016-03-21 13:12:59 -0600103
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700104import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
Felipe Lemeb85a6372016-01-14 16:16:16 -0800105import static org.xmlpull.v1.XmlPullParser.END_TAG;
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700106import static org.xmlpull.v1.XmlPullParser.START_TAG;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -0700107
Dianne Hackborn88e98df2015-03-23 13:29:14 -0700108import android.Manifest;
Felipe Lemef3e40642016-06-07 17:28:08 -0700109import android.annotation.IntDef;
Jeff Sharkey2e471452018-01-19 18:02:47 +0900110import android.annotation.NonNull;
Felipe Lemebc853dd2016-09-08 13:26:55 -0700111import android.annotation.Nullable;
Dianne Hackborn497175b2014-07-01 12:56:08 -0700112import android.app.ActivityManager;
Sudheer Shankae7361852017-03-07 11:51:46 -0800113import android.app.ActivityManagerInternal;
Dianne Hackborn88e98df2015-03-23 13:29:14 -0700114import android.app.AppGlobals;
Svet Ganov16a16892015-04-16 10:32:04 -0700115import android.app.AppOpsManager;
Jeff Sharkeya4620792011-05-20 15:29:23 -0700116import android.app.IActivityManager;
Dianne Hackbornd23e0d62015-05-15 16:36:12 -0700117import android.app.IUidObserver;
Jeff Sharkey497e4432011-06-14 17:27:29 -0700118import android.app.Notification;
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -0700119import android.app.NotificationManager;
Jeff Sharkey497e4432011-06-14 17:27:29 -0700120import android.app.PendingIntent;
Amith Yamasani15e472352015-04-24 19:06:07 -0700121import android.app.usage.UsageStatsManagerInternal;
Jeff Sharkeya4620792011-05-20 15:29:23 -0700122import android.content.BroadcastReceiver;
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -0700123import android.content.ComponentName;
Jeff Sharkey36b414b2018-03-30 11:00:03 -0600124import android.content.ContentResolver;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -0700125import android.content.Context;
Jeff Sharkeya4620792011-05-20 15:29:23 -0700126import android.content.Intent;
127import android.content.IntentFilter;
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -0700128import android.content.pm.ApplicationInfo;
Dianne Hackborn88e98df2015-03-23 13:29:14 -0700129import android.content.pm.IPackageManager;
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -0700130import android.content.pm.PackageManager;
Amith Yamasani15e472352015-04-24 19:06:07 -0700131import android.content.pm.PackageManager.NameNotFoundException;
Jeff Sharkey8a8b5812012-03-21 18:13:36 -0700132import android.content.pm.UserInfo;
Jeff Sharkey497e4432011-06-14 17:27:29 -0700133import android.content.res.Resources;
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -0700134import android.net.ConnectivityManager;
Jeff Sharkeyb43a2922017-09-13 17:30:45 -0600135import android.net.ConnectivityManager.NetworkCallback;
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700136import android.net.IConnectivityManager;
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -0700137import android.net.INetworkManagementEventObserver;
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -0700138import android.net.INetworkPolicyListener;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -0700139import android.net.INetworkPolicyManager;
Jeff Sharkey75279902011-05-24 18:39:45 -0700140import android.net.INetworkStatsService;
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -0700141import android.net.LinkProperties;
Jeff Sharkeyb43a2922017-09-13 17:30:45 -0600142import android.net.Network;
143import android.net.NetworkCapabilities;
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -0700144import android.net.NetworkIdentity;
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700145import android.net.NetworkPolicy;
Jeff Sharkey53313d72017-07-13 16:47:32 -0600146import android.net.NetworkPolicyManager;
Jeff Sharkeyf0ceede2011-08-02 17:22:34 -0700147import android.net.NetworkQuotaInfo;
Jeff Sharkeyb43a2922017-09-13 17:30:45 -0600148import android.net.NetworkRequest;
Jeff Sharkey9252b342018-01-19 07:58:35 +0900149import android.net.NetworkSpecifier;
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700150import android.net.NetworkState;
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700151import android.net.NetworkStats;
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -0700152import android.net.NetworkTemplate;
Jeff Sharkey9252b342018-01-19 07:58:35 +0900153import android.net.StringNetworkSpecifier;
Jeff Sharkey53313d72017-07-13 16:47:32 -0600154import android.net.TrafficStats;
Jeff Sharkey9f6e4ba2012-04-19 23:01:08 -0700155import android.net.wifi.WifiConfiguration;
Jeff Sharkey9f6e4ba2012-04-19 23:01:08 -0700156import android.net.wifi.WifiManager;
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700157import android.os.BestClock;
Jeff Sharkeyf0ceede2011-08-02 17:22:34 -0700158import android.os.Binder;
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700159import android.os.Environment;
160import android.os.Handler;
Amith Yamasani450a16b2013-09-18 16:28:50 -0700161import android.os.HandlerThread;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700162import android.os.IDeviceIdleController;
Ashish Sharma50fd36d2011-06-15 19:34:53 -0700163import android.os.INetworkManagementService;
Jeff Sharkey4414cea2011-06-24 17:05:24 -0700164import android.os.Message;
Jeff Sharkey163e6442011-10-31 16:37:52 -0700165import android.os.MessageQueue.IdleHandler;
Ammar Aijazi6ce48e22017-03-28 15:43:22 -0700166import android.os.PersistableBundle;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700167import android.os.PowerManager;
Makoto Onuki2eccd022017-11-01 13:44:23 -0700168import android.os.PowerManager.ServiceType;
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700169import android.os.PowerManagerInternal;
Jeff Sharkey43d2a172017-07-12 10:50:42 -0600170import android.os.PowerSaveState;
Fyodor Kupolov311b9fa2016-12-02 16:24:35 -0800171import android.os.Process;
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -0700172import android.os.RemoteCallbackList;
Jeff Sharkeya4620792011-05-20 15:29:23 -0700173import android.os.RemoteException;
Jeff Sharkey7474fe7b2016-03-21 13:12:59 -0600174import android.os.ResultReceiver;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700175import android.os.ServiceManager;
Dianne Hackborn354736e2016-08-22 17:00:05 -0700176import android.os.ShellCallback;
Jeff Sharkey9911a282018-02-14 22:29:11 -0700177import android.os.SystemClock;
Jeff Sharkey53313d72017-07-13 16:47:32 -0600178import android.os.SystemProperties;
Felipe Leme873a83a2016-09-07 11:34:10 -0700179import android.os.Trace;
Dianne Hackbornf02b60a2012-08-16 10:48:27 -0700180import android.os.UserHandle;
Amith Yamasani258848d2012-08-10 17:06:33 -0700181import android.os.UserManager;
Jeff Sharkey3a844fc2011-08-16 14:37:57 -0700182import android.provider.Settings;
Narayan Kamath94bcdbc2017-07-17 15:32:53 +0100183import android.provider.Settings.Global;
Ammar Aijazi6ce48e22017-03-28 15:43:22 -0700184import android.telephony.CarrierConfigManager;
Jeff Sharkey53313d72017-07-13 16:47:32 -0600185import android.telephony.SubscriptionInfo;
Jeff Sharkey32566012014-12-02 18:30:14 -0800186import android.telephony.SubscriptionManager;
Jeff Sharkey53313d72017-07-13 16:47:32 -0600187import android.telephony.SubscriptionPlan;
Jeff Sharkey22c055e2011-06-12 21:13:51 -0700188import android.telephony.TelephonyManager;
Chris Wren8a3d56c2016-08-01 15:52:52 -0400189import android.text.TextUtils;
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -0700190import android.text.format.DateUtils;
Jeff Sharkey497e4432011-06-14 17:27:29 -0700191import android.text.format.Formatter;
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700192import android.util.ArrayMap;
193import android.util.ArraySet;
Dianne Hackborn39606a02012-07-31 17:54:35 -0700194import android.util.AtomicFile;
Jeff Sharkey9252b342018-01-19 07:58:35 +0900195import android.util.DataUnit;
Jeff Sharkeyb3d59572011-09-07 17:20:27 -0700196import android.util.Log;
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -0700197import android.util.Pair;
Jeff Sharkey17bebd22017-07-19 21:00:38 -0600198import android.util.RecurrenceRule;
Jeff Sharkeya4620792011-05-20 15:29:23 -0700199import android.util.Slog;
Jeff Sharkey17bebd22017-07-19 21:00:38 -0600200import android.util.SparseArray;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -0700201import android.util.SparseBooleanArray;
202import android.util.SparseIntArray;
Jeff Sharkey9252b342018-01-19 07:58:35 +0900203import android.util.SparseLongArray;
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700204import android.util.Xml;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -0700205
Jeff Sharkey497e4432011-06-14 17:27:29 -0700206import com.android.internal.R;
Felipe Lemef0823852016-06-08 13:43:08 -0700207import com.android.internal.annotations.GuardedBy;
Jeff Sharkey8b2c3a142012-11-12 11:45:05 -0800208import com.android.internal.annotations.VisibleForTesting;
Chris Wren193ae6b2017-03-31 15:17:11 -0400209import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
Geoffrey Pitschaf759c52017-02-15 09:35:38 -0500210import com.android.internal.notification.SystemNotificationChannels;
Ammar Aijazi6ce48e22017-03-28 15:43:22 -0700211import com.android.internal.telephony.PhoneConstants;
Jeff Sharkey32566012014-12-02 18:30:14 -0800212import com.android.internal.util.ArrayUtils;
Sudheer Shankac53c47f2018-01-16 12:01:00 -0800213import com.android.internal.util.ConcurrentUtils;
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -0600214import com.android.internal.util.DumpUtils;
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700215import com.android.internal.util.FastXmlSerializer;
Jeff Sharkey8fc27e82012-04-04 20:40:58 -0700216import com.android.internal.util.IndentingPrintWriter;
Jeff Sharkey17bebd22017-07-19 21:00:38 -0600217import com.android.internal.util.Preconditions;
Makoto Onuki49392d32018-04-11 13:51:02 -0700218import com.android.internal.util.StatLogger;
Jeff Sharkeydc988062015-09-14 10:09:47 -0700219import com.android.server.EventLogTags;
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700220import com.android.server.LocalServices;
Makoto Onuki8e777332017-03-28 11:25:47 -0700221import com.android.server.ServiceThread;
Felipe Lemea9505cc2016-02-26 10:28:41 -0800222import com.android.server.SystemConfig;
Jeff Sharkey43d2a172017-07-12 10:50:42 -0600223
Jeff Sharkey7474fe7b2016-03-21 13:12:59 -0600224import libcore.io.IoUtils;
225
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700226import org.xmlpull.v1.XmlPullParser;
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700227import org.xmlpull.v1.XmlSerializer;
228
229import java.io.File;
Jeff Sharkey1b861272011-05-22 00:34:52 -0700230import java.io.FileDescriptor;
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700231import java.io.FileInputStream;
232import java.io.FileNotFoundException;
233import java.io.FileOutputStream;
234import java.io.IOException;
Jeff Sharkey1b861272011-05-22 00:34:52 -0700235import java.io.PrintWriter;
Felipe Lemef3e40642016-06-07 17:28:08 -0700236import java.lang.annotation.Retention;
237import java.lang.annotation.RetentionPolicy;
Wojciech Staszkiewicz9e9e2e72015-05-08 14:58:46 +0100238import java.nio.charset.StandardCharsets;
Jeff Sharkey9911a282018-02-14 22:29:11 -0700239import java.time.Clock;
Remi NGUYEN VANbed7b972018-04-02 15:48:19 +0900240import java.time.Instant;
Jeff Sharkey17bebd22017-07-19 21:00:38 -0600241import java.time.ZoneId;
Jeff Sharkey9911a282018-02-14 22:29:11 -0700242import java.time.ZoneOffset;
Jeff Sharkey53313d72017-07-13 16:47:32 -0600243import java.time.ZonedDateTime;
Remi NGUYEN VANbed7b972018-04-02 15:48:19 +0900244import java.time.temporal.ChronoUnit;
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700245import java.util.ArrayList;
Ammar Aijazi6ce48e22017-03-28 15:43:22 -0700246import java.util.Calendar;
Jeff Sharkey43d2a172017-07-12 10:50:42 -0600247import java.util.List;
Chris Wren193ae6b2017-03-31 15:17:11 -0400248import java.util.Objects;
Sudheer Shanka04d61ae2018-01-17 12:16:57 -0800249import java.util.Set;
Fyodor Kupolov311b9fa2016-12-02 16:24:35 -0800250import java.util.concurrent.CountDownLatch;
251import java.util.concurrent.TimeUnit;
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700252
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -0700253/**
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -0700254 * Service that maintains low-level network policy rules, using
255 * {@link NetworkStatsService} statistics to drive those rules.
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -0700256 * <p>
257 * Derives active rules by combining a given policy with other system status,
258 * and delivers to listeners, such as {@link ConnectivityManager}, for
259 * enforcement.
Felipe Lemef0823852016-06-08 13:43:08 -0700260 *
261 * <p>
Sudheer Shankac9d94072017-02-22 22:13:55 +0000262 * This class uses 2-3 locks to synchronize state:
Felipe Lemef0823852016-06-08 13:43:08 -0700263 * <ul>
264 * <li>{@code mUidRulesFirstLock}: used to guard state related to individual UIDs (such as firewall
265 * rules).
266 * <li>{@code mNetworkPoliciesSecondLock}: used to guard state related to network interfaces (such
267 * as network policies).
Sudheer Shankac9d94072017-02-22 22:13:55 +0000268 * <li>{@code allLocks}: not a "real" lock, but an indication (through @GuardedBy) that all locks
269 * must be held.
Felipe Lemef0823852016-06-08 13:43:08 -0700270 * </ul>
271 *
272 * <p>
273 * As such, methods that require synchronization have the following prefixes:
274 * <ul>
275 * <li>{@code UL()}: require the "UID" lock ({@code mUidRulesFirstLock}).
276 * <li>{@code NL()}: require the "Network" lock ({@code mNetworkPoliciesSecondLock}).
Sudheer Shankac9d94072017-02-22 22:13:55 +0000277 * <li>{@code AL()}: require all locks, which must be obtained in order ({@code mUidRulesFirstLock}
278 * first, then {@code mNetworkPoliciesSecondLock}, then {@code mYetAnotherGuardThirdLock}, etc..
Felipe Lemef0823852016-06-08 13:43:08 -0700279 * </ul>
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -0700280 */
Xiaohui Chen8dca36d2015-06-19 12:44:59 -0700281public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
Sudheer Shanka352dc572017-09-22 17:09:38 -0700282 static final String TAG = NetworkPolicyLogger.TAG;
283 private static final boolean LOGD = NetworkPolicyLogger.LOGD;
284 private static final boolean LOGV = NetworkPolicyLogger.LOGV;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -0700285
Remi NGUYEN VAN5a89f942018-03-30 21:17:42 +0900286 /**
287 * No opportunistic quota could be calculated from user data plan or data settings.
288 */
289 public static final int OPPORTUNISTIC_QUOTA_UNKNOWN = -1;
290
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -0700291 private static final int VERSION_INIT = 1;
292 private static final int VERSION_ADDED_SNOOZE = 2;
Jeff Sharkey46645002011-07-27 21:11:21 -0700293 private static final int VERSION_ADDED_RESTRICT_BACKGROUND = 3;
Jeff Sharkeyf60d0af2011-11-30 15:28:02 -0800294 private static final int VERSION_ADDED_METERED = 4;
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -0800295 private static final int VERSION_SPLIT_SNOOZE = 5;
Jeff Sharkey9bf31502012-03-09 17:07:21 -0800296 private static final int VERSION_ADDED_TIMEZONE = 6;
Jeff Sharkey837f9242012-03-20 16:52:20 -0700297 private static final int VERSION_ADDED_INFERRED = 7;
Jeff Sharkey8a8b5812012-03-21 18:13:36 -0700298 private static final int VERSION_SWITCH_APP_ID = 8;
Jeff Sharkey8fc27e82012-04-04 20:40:58 -0700299 private static final int VERSION_ADDED_NETWORK_ID = 9;
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -0700300 private static final int VERSION_SWITCH_UID = 10;
Jeff Sharkey17bebd22017-07-19 21:00:38 -0600301 private static final int VERSION_ADDED_CYCLE = 11;
302 private static final int VERSION_LATEST = VERSION_ADDED_CYCLE;
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700303
Jeff Sharkey8b2c3a142012-11-12 11:45:05 -0800304 @VisibleForTesting
Chris Wren193ae6b2017-03-31 15:17:11 -0400305 public static final int TYPE_WARNING = SystemMessage.NOTE_NET_WARNING;
Jeff Sharkey8b2c3a142012-11-12 11:45:05 -0800306 @VisibleForTesting
Chris Wren193ae6b2017-03-31 15:17:11 -0400307 public static final int TYPE_LIMIT = SystemMessage.NOTE_NET_LIMIT;
Jeff Sharkey8b2c3a142012-11-12 11:45:05 -0800308 @VisibleForTesting
Chris Wren193ae6b2017-03-31 15:17:11 -0400309 public static final int TYPE_LIMIT_SNOOZED = SystemMessage.NOTE_NET_LIMIT_SNOOZED;
Jeff Sharkey2e471452018-01-19 18:02:47 +0900310 @VisibleForTesting
311 public static final int TYPE_RAPID = SystemMessage.NOTE_NET_RAPID;
Jeff Sharkey497e4432011-06-14 17:27:29 -0700312
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700313 private static final String TAG_POLICY_LIST = "policy-list";
314 private static final String TAG_NETWORK_POLICY = "network-policy";
Jeff Sharkey17bebd22017-07-19 21:00:38 -0600315 private static final String TAG_SUBSCRIPTION_PLAN = "subscription-plan";
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700316 private static final String TAG_UID_POLICY = "uid-policy";
Jeff Sharkey8a8b5812012-03-21 18:13:36 -0700317 private static final String TAG_APP_POLICY = "app-policy";
Felipe Lemeb85a6372016-01-14 16:16:16 -0800318 private static final String TAG_WHITELIST = "whitelist";
319 private static final String TAG_RESTRICT_BACKGROUND = "restrict-background";
Felipe Lemea9505cc2016-02-26 10:28:41 -0800320 private static final String TAG_REVOKED_RESTRICT_BACKGROUND = "revoked-restrict-background";
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700321
322 private static final String ATTR_VERSION = "version";
Jeff Sharkey46645002011-07-27 21:11:21 -0700323 private static final String ATTR_RESTRICT_BACKGROUND = "restrictBackground";
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700324 private static final String ATTR_NETWORK_TEMPLATE = "networkTemplate";
325 private static final String ATTR_SUBSCRIBER_ID = "subscriberId";
Jeff Sharkey8fc27e82012-04-04 20:40:58 -0700326 private static final String ATTR_NETWORK_ID = "networkId";
Jeff Sharkey17bebd22017-07-19 21:00:38 -0600327 @Deprecated private static final String ATTR_CYCLE_DAY = "cycleDay";
328 @Deprecated private static final String ATTR_CYCLE_TIMEZONE = "cycleTimezone";
329 private static final String ATTR_CYCLE_START = "cycleStart";
330 private static final String ATTR_CYCLE_END = "cycleEnd";
331 private static final String ATTR_CYCLE_PERIOD = "cyclePeriod";
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700332 private static final String ATTR_WARNING_BYTES = "warningBytes";
333 private static final String ATTR_LIMIT_BYTES = "limitBytes";
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -0700334 private static final String ATTR_LAST_SNOOZE = "lastSnooze";
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -0800335 private static final String ATTR_LAST_WARNING_SNOOZE = "lastWarningSnooze";
336 private static final String ATTR_LAST_LIMIT_SNOOZE = "lastLimitSnooze";
Jeff Sharkeyf60d0af2011-11-30 15:28:02 -0800337 private static final String ATTR_METERED = "metered";
Jeff Sharkey837f9242012-03-20 16:52:20 -0700338 private static final String ATTR_INFERRED = "inferred";
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700339 private static final String ATTR_UID = "uid";
Jeff Sharkey8a8b5812012-03-21 18:13:36 -0700340 private static final String ATTR_APP_ID = "appId";
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700341 private static final String ATTR_POLICY = "policy";
Jeff Sharkey17bebd22017-07-19 21:00:38 -0600342 private static final String ATTR_SUB_ID = "subId";
343 private static final String ATTR_TITLE = "title";
344 private static final String ATTR_SUMMARY = "summary";
345 private static final String ATTR_LIMIT_BEHAVIOR = "limitBehavior";
346 private static final String ATTR_USAGE_BYTES = "usageBytes";
347 private static final String ATTR_USAGE_TIME = "usageTime";
Jeff Sharkeyb74799882017-07-28 16:55:41 -0600348 private static final String ATTR_OWNER_PACKAGE = "ownerPackage";
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700349
Jeff Sharkey8b2c3a142012-11-12 11:45:05 -0800350 private static final String ACTION_ALLOW_BACKGROUND =
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -0800351 "com.android.server.net.action.ALLOW_BACKGROUND";
Jeff Sharkey8b2c3a142012-11-12 11:45:05 -0800352 private static final String ACTION_SNOOZE_WARNING =
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -0800353 "com.android.server.net.action.SNOOZE_WARNING";
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -0700354 private static final String ACTION_SNOOZE_RAPID =
355 "com.android.server.net.action.SNOOZE_RAPID";
Jeff Sharkey3a844fc2011-08-16 14:37:57 -0700356
Sudheer Shankac53c47f2018-01-16 12:01:00 -0800357 /**
358 * Indicates the maximum wait time for admin data to be available;
359 */
360 private static final long WAIT_FOR_ADMIN_DATA_TIMEOUT_MS = 10_000;
361
Jeff Sharkey36b414b2018-03-30 11:00:03 -0600362 private static final long QUOTA_UNLIMITED_DEFAULT = DataUnit.MEBIBYTES.toBytes(20);
363 private static final float QUOTA_LIMITED_DEFAULT = 0.1f;
364 private static final float QUOTA_FRAC_JOBS_DEFAULT = 0.5f;
365 private static final float QUOTA_FRAC_MULTIPATH_DEFAULT = 0.5f;
366
Svetoslav Ganov24c27752016-08-31 18:09:00 -0700367 private static final int MSG_RULES_CHANGED = 1;
Jeff Sharkey6f7af032011-11-01 18:25:15 -0700368 private static final int MSG_METERED_IFACES_CHANGED = 2;
Jeff Sharkey7e25b0e2011-11-08 15:43:12 -0800369 private static final int MSG_LIMIT_REACHED = 5;
Jeff Sharkey1f8ea2d2012-02-07 12:05:43 -0800370 private static final int MSG_RESTRICT_BACKGROUND_CHANGED = 6;
Jeff Sharkeye19f39b2012-05-24 10:21:16 -0700371 private static final int MSG_ADVISE_PERSIST_THRESHOLD = 7;
Amith Yamasani3646cbd2016-04-13 14:04:53 -0700372 private static final int MSG_UPDATE_INTERFACE_QUOTA = 10;
373 private static final int MSG_REMOVE_INTERFACE_QUOTA = 11;
Felipe Leme0ecfcd12016-09-06 12:49:48 -0700374 private static final int MSG_POLICIES_CHANGED = 13;
Felipe Leme03e95e22016-09-09 09:25:31 -0700375 private static final int MSG_RESET_FIREWALL_RULES_BY_UID = 15;
Jeff Sharkey9252b342018-01-19 07:58:35 +0900376 private static final int MSG_SUBSCRIPTION_OVERRIDE = 16;
Sudheer Shanka04d61ae2018-01-17 12:16:57 -0800377 private static final int MSG_METERED_RESTRICTED_PACKAGES_CHANGED = 17;
Makoto Onuki3f1bf5f2018-04-04 15:29:00 -0700378 private static final int MSG_SET_NETWORK_TEMPLATE_ENABLED = 18;
Jeff Sharkey4414cea2011-06-24 17:05:24 -0700379
Makoto Onuki8e777332017-03-28 11:25:47 -0700380 private static final int UID_MSG_STATE_CHANGED = 100;
381 private static final int UID_MSG_GONE = 101;
382
Jeff Sharkey003d3e62018-03-30 14:35:04 -0600383 private static final String PROP_SUB_PLAN_OWNER = "persist.sys.sub_plan_owner";
384
Jeff Sharkey75279902011-05-24 18:39:45 -0700385 private final Context mContext;
386 private final IActivityManager mActivityManager;
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700387 private NetworkStatsManagerInternal mNetworkStats;
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -0700388 private final INetworkManagementService mNetworkManager;
Amith Yamasani15e472352015-04-24 19:06:07 -0700389 private UsageStatsManagerInternal mUsageStats;
Jeff Sharkey9911a282018-02-14 22:29:11 -0700390 private final Clock mClock;
Stuart Scotte3e314d2015-04-20 14:07:45 -0700391 private final UserManager mUserManager;
Ammar Aijazi6ce48e22017-03-28 15:43:22 -0700392 private final CarrierConfigManager mCarrierConfigManager;
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700393
394 private IConnectivityManager mConnManager;
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700395 private PowerManagerInternal mPowerManagerInternal;
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700396 private IDeviceIdleController mDeviceIdleController;
jackqdyulei29c82ab2017-03-10 14:09:16 -0800397 @GuardedBy("mUidRulesFirstLock")
398 private PowerSaveState mRestrictBackgroundPowerState;
399
400 // Store the status of restrict background before turning on battery saver.
401 // Used to restore mRestrictBackground when battery saver is turned off.
402 private boolean mRestrictBackgroundBeforeBsm;
Jeff Sharkeya4620792011-05-20 15:29:23 -0700403
Sudheer Shanka543339f2017-07-28 15:18:07 -0700404 // Denotes the status of restrict background read from disk.
405 private boolean mLoadedRestrictBackground;
406
Felipe Lemef0823852016-06-08 13:43:08 -0700407 // See main javadoc for instructions on how to use these locks.
408 final Object mUidRulesFirstLock = new Object();
409 final Object mNetworkPoliciesSecondLock = new Object();
Jeff Sharkeya4620792011-05-20 15:29:23 -0700410
Felipe Lemef0823852016-06-08 13:43:08 -0700411 @GuardedBy("allLocks") volatile boolean mSystemReady;
412
Felipe Lemef0823852016-06-08 13:43:08 -0700413 @GuardedBy("mUidRulesFirstLock") volatile boolean mRestrictBackground;
414 @GuardedBy("mUidRulesFirstLock") volatile boolean mRestrictPower;
415 @GuardedBy("mUidRulesFirstLock") volatile boolean mDeviceIdleMode;
jackqdyulei29c82ab2017-03-10 14:09:16 -0800416 // Store whether user flipped restrict background in battery saver mode
417 @GuardedBy("mUidRulesFirstLock") volatile boolean mRestrictBackgroundChangedInBsm;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -0700418
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -0700419 private final boolean mSuppressDefaultPolicy;
420
Sudheer Shankac53c47f2018-01-16 12:01:00 -0800421 private final CountDownLatch mAdminDataAvailableLatch = new CountDownLatch(1);
422
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -0700423 /** Defined network policies. */
Jeff Sharkey4635f102017-09-01 11:27:13 -0600424 @GuardedBy("mNetworkPoliciesSecondLock")
Jeff Sharkey32566012014-12-02 18:30:14 -0800425 final ArrayMap<NetworkTemplate, NetworkPolicy> mNetworkPolicy = new ArrayMap<>();
Jeff Sharkey22c055e2011-06-12 21:13:51 -0700426
Jeff Sharkeyb74799882017-07-28 16:55:41 -0600427 /** Map from subId to subscription plans. */
Jeff Sharkey4635f102017-09-01 11:27:13 -0600428 @GuardedBy("mNetworkPoliciesSecondLock")
Jeff Sharkey17bebd22017-07-19 21:00:38 -0600429 final SparseArray<SubscriptionPlan[]> mSubscriptionPlans = new SparseArray<>();
Jeff Sharkeyb74799882017-07-28 16:55:41 -0600430 /** Map from subId to package name that owns subscription plans. */
Jeff Sharkey4635f102017-09-01 11:27:13 -0600431 @GuardedBy("mNetworkPoliciesSecondLock")
Jeff Sharkeyb74799882017-07-28 16:55:41 -0600432 final SparseArray<String> mSubscriptionPlansOwner = new SparseArray<>();
Jeff Sharkey17bebd22017-07-19 21:00:38 -0600433
Jeff Sharkey9252b342018-01-19 07:58:35 +0900434 /** Map from subId to daily opportunistic quota. */
435 @GuardedBy("mNetworkPoliciesSecondLock")
436 final SparseLongArray mSubscriptionOpportunisticQuota = new SparseLongArray();
437
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -0700438 /** Defined UID policies. */
Felipe Lemef0823852016-06-08 13:43:08 -0700439 @GuardedBy("mUidRulesFirstLock") final SparseIntArray mUidPolicy = new SparseIntArray();
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -0700440 /** Currently derived rules for each UID. */
Felipe Lemef0823852016-06-08 13:43:08 -0700441 @GuardedBy("mUidRulesFirstLock") final SparseIntArray mUidRules = new SparseIntArray();
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700442
Felipe Lemef0823852016-06-08 13:43:08 -0700443 @GuardedBy("mUidRulesFirstLock")
Jeff Sharkeydc988062015-09-14 10:09:47 -0700444 final SparseIntArray mUidFirewallStandbyRules = new SparseIntArray();
Felipe Lemef0823852016-06-08 13:43:08 -0700445 @GuardedBy("mUidRulesFirstLock")
Jeff Sharkeydc988062015-09-14 10:09:47 -0700446 final SparseIntArray mUidFirewallDozableRules = new SparseIntArray();
Felipe Lemef0823852016-06-08 13:43:08 -0700447 @GuardedBy("mUidRulesFirstLock")
Felipe Leme011b98f2016-02-10 17:28:31 -0800448 final SparseIntArray mUidFirewallPowerSaveRules = new SparseIntArray();
Jeff Sharkeydc988062015-09-14 10:09:47 -0700449
Jeff Sharkey02e21d62011-07-17 15:53:33 -0700450 /** Set of states for the child firewall chains. True if the chain is active. */
Felipe Lemef0823852016-06-08 13:43:08 -0700451 @GuardedBy("mUidRulesFirstLock")
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700452 final SparseBooleanArray mFirewallChainStates = new SparseBooleanArray();
453
Jeff Sharkey32566012014-12-02 18:30:14 -0800454 /**
455 * UIDs that have been white-listed to always be able to have network access
Dianne Hackborn4a503b12015-08-06 22:19:06 -0700456 * in power save mode, except device idle (doze) still applies.
457 * TODO: An int array might be sufficient
458 */
Felipe Lemef0823852016-06-08 13:43:08 -0700459 @GuardedBy("mUidRulesFirstLock")
Dianne Hackborn4a503b12015-08-06 22:19:06 -0700460 private final SparseBooleanArray mPowerSaveWhitelistExceptIdleAppIds = new SparseBooleanArray();
461
462 /**
463 * UIDs that have been white-listed to always be able to have network access
Jeff Sharkey32566012014-12-02 18:30:14 -0800464 * in power save mode.
Amith Yamasaniaf575b92015-05-29 15:35:26 -0700465 * TODO: An int array might be sufficient
Jeff Sharkey32566012014-12-02 18:30:14 -0800466 */
Felipe Lemef0823852016-06-08 13:43:08 -0700467 @GuardedBy("mUidRulesFirstLock")
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700468 private final SparseBooleanArray mPowerSaveWhitelistAppIds = new SparseBooleanArray();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -0700469
Felipe Lemef0823852016-06-08 13:43:08 -0700470 @GuardedBy("mUidRulesFirstLock")
Amith Yamasaniaf575b92015-05-29 15:35:26 -0700471 private final SparseBooleanArray mPowerSaveTempWhitelistAppIds = new SparseBooleanArray();
472
Felipe Lemeb85a6372016-01-14 16:16:16 -0800473 /**
Felipe Lemea9505cc2016-02-26 10:28:41 -0800474 * UIDs that have been initially white-listed by system to avoid restricted background.
475 */
Felipe Lemef0823852016-06-08 13:43:08 -0700476 @GuardedBy("mUidRulesFirstLock")
Felipe Lemea9505cc2016-02-26 10:28:41 -0800477 private final SparseBooleanArray mDefaultRestrictBackgroundWhitelistUids =
478 new SparseBooleanArray();
479
480 /**
481 * UIDs that have been initially white-listed by system to avoid restricted background,
482 * but later revoked by user.
483 */
Felipe Lemef0823852016-06-08 13:43:08 -0700484 @GuardedBy("mUidRulesFirstLock")
Felipe Lemea9505cc2016-02-26 10:28:41 -0800485 private final SparseBooleanArray mRestrictBackgroundWhitelistRevokedUids =
486 new SparseBooleanArray();
487
Jeff Sharkeyfdfef572011-06-16 15:07:48 -0700488 /** Set of ifaces that are metered. */
Felipe Lemef0823852016-06-08 13:43:08 -0700489 @GuardedBy("mNetworkPoliciesSecondLock")
Jeff Sharkey32566012014-12-02 18:30:14 -0800490 private ArraySet<String> mMeteredIfaces = new ArraySet<>();
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -0700491 /** Set of over-limit templates that have been notified. */
Felipe Lemef0823852016-06-08 13:43:08 -0700492 @GuardedBy("mNetworkPoliciesSecondLock")
Jeff Sharkey32566012014-12-02 18:30:14 -0800493 private final ArraySet<NetworkTemplate> mOverLimitNotified = new ArraySet<>();
Jeff Sharkeyfdfef572011-06-16 15:07:48 -0700494
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -0700495 /** Set of currently active {@link Notification} tags. */
Felipe Lemef0823852016-06-08 13:43:08 -0700496 @GuardedBy("mNetworkPoliciesSecondLock")
Chris Wren193ae6b2017-03-31 15:17:11 -0400497 private final ArraySet<NotificationId> mActiveNotifs = new ArraySet<>();
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -0700498
Dianne Hackbornd23e0d62015-05-15 16:36:12 -0700499 /** Foreground at UID granularity. */
Felipe Lemef0823852016-06-08 13:43:08 -0700500 @GuardedBy("mUidRulesFirstLock")
Jeff Sharkey32566012014-12-02 18:30:14 -0800501 final SparseIntArray mUidState = new SparseIntArray();
Dianne Hackborn497175b2014-07-01 12:56:08 -0700502
Jeff Sharkeyb43a2922017-09-13 17:30:45 -0600503 /** Map from network ID to last observed meteredness state */
504 @GuardedBy("mNetworkPoliciesSecondLock")
505 private final SparseBooleanArray mNetworkMetered = new SparseBooleanArray();
506
Jeff Sharkey9252b342018-01-19 07:58:35 +0900507 /** Map from netId to subId as of last update */
508 @GuardedBy("mNetworkPoliciesSecondLock")
509 private final SparseIntArray mNetIdToSubId = new SparseIntArray();
510
Sudheer Shanka04d61ae2018-01-17 12:16:57 -0800511 /**
512 * Indicates the uids restricted by admin from accessing metered data. It's a mapping from
513 * userId to restricted uids which belong to that user.
514 */
515 @GuardedBy("mUidRulesFirstLock")
516 private final SparseArray<Set<Integer>> mMeteredRestrictedUids = new SparseArray<>();
517
Jeff Sharkey32566012014-12-02 18:30:14 -0800518 private final RemoteCallbackList<INetworkPolicyListener>
519 mListeners = new RemoteCallbackList<>();
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -0700520
Dianne Hackborn497175b2014-07-01 12:56:08 -0700521 final Handler mHandler;
Sudheer Shankaed25ce62017-03-29 20:46:30 -0700522 @VisibleForTesting
523 public final Handler mUidEventHandler;
Makoto Onuki8e777332017-03-28 11:25:47 -0700524
525 private final ServiceThread mUidEventThread;
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700526
Felipe Lemef0823852016-06-08 13:43:08 -0700527 @GuardedBy("allLocks")
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700528 private final AtomicFile mPolicyFile;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -0700529
Svet Ganov16a16892015-04-16 10:32:04 -0700530 private final AppOpsManager mAppOps;
531
Amith Yamasani2a4ac4e2016-02-12 12:43:15 -0800532 private final IPackageManager mIPm;
533
Sudheer Shankae7361852017-03-07 11:51:46 -0800534 private ActivityManagerInternal mActivityManagerInternal;
535
Sudheer Shanka352dc572017-09-22 17:09:38 -0700536 private final NetworkPolicyLogger mLogger = new NetworkPolicyLogger();
Felipe Lemeb85a6372016-01-14 16:16:16 -0800537
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -0700538 // TODO: keep whitelist of system-critical services that should never have
539 // rules enforced, such as system, phone, and radio UIDs.
540
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -0700541 // TODO: migrate notifications to SystemUI
542
Makoto Onuki49392d32018-04-11 13:51:02 -0700543
544 interface Stats {
545 int UPDATE_NETWORK_ENABLED = 0;
546 int IS_UID_NETWORKING_BLOCKED = 1;
547
548 int COUNT = IS_UID_NETWORKING_BLOCKED + 1;
549 }
550
551 public final StatLogger mStatLogger = new StatLogger(new String[] {
552 "updateNetworkEnabledNL()",
553 "isUidNetworkingBlocked()",
554 });
555
Jeff Sharkey75279902011-05-24 18:39:45 -0700556 public NetworkPolicyManagerService(Context context, IActivityManager activityManager,
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700557 INetworkManagementService networkManagement) {
558 this(context, activityManager, networkManagement, AppGlobals.getPackageManager(),
559 getDefaultClock(), getDefaultSystemDir(), false);
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700560 }
561
Jeff Sharkey9911a282018-02-14 22:29:11 -0700562 private static @NonNull File getDefaultSystemDir() {
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700563 return new File(Environment.getDataDirectory(), "system");
564 }
565
Jeff Sharkey9911a282018-02-14 22:29:11 -0700566 private static @NonNull Clock getDefaultClock() {
567 return new BestClock(ZoneOffset.UTC, SystemClock.currentNetworkTimeClock(),
568 Clock.systemUTC());
569 }
570
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700571 public NetworkPolicyManagerService(Context context, IActivityManager activityManager,
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700572 INetworkManagementService networkManagement, IPackageManager pm, Clock clock,
573 File systemDir, boolean suppressDefaultPolicy) {
Jeff Sharkeya4620792011-05-20 15:29:23 -0700574 mContext = checkNotNull(context, "missing context");
575 mActivityManager = checkNotNull(activityManager, "missing activityManager");
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -0700576 mNetworkManager = checkNotNull(networkManagement, "missing networkManagement");
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700577 mDeviceIdleController = IDeviceIdleController.Stub.asInterface(ServiceManager.getService(
Dianne Hackborn1958e5e2015-06-12 18:11:41 -0700578 Context.DEVICE_IDLE_CONTROLLER));
Jeff Sharkey9911a282018-02-14 22:29:11 -0700579 mClock = checkNotNull(clock, "missing Clock");
Stuart Scotte3e314d2015-04-20 14:07:45 -0700580 mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
Ammar Aijazi6ce48e22017-03-28 15:43:22 -0700581 mCarrierConfigManager = mContext.getSystemService(CarrierConfigManager.class);
Felipe Leme3d3308d2016-08-23 17:41:47 -0700582 mIPm = pm;
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700583
Amith Yamasani450a16b2013-09-18 16:28:50 -0700584 HandlerThread thread = new HandlerThread(TAG);
585 thread.start();
586 mHandler = new Handler(thread.getLooper(), mHandlerCallback);
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700587
Makoto Onuki8e777332017-03-28 11:25:47 -0700588 // We create another thread for the UID events, which are more time-critical.
589 mUidEventThread = new ServiceThread(TAG + ".uid", Process.THREAD_PRIORITY_FOREGROUND,
590 /*allowIo=*/ false);
591 mUidEventThread.start();
592 mUidEventHandler = new Handler(mUidEventThread.getLooper(), mUidEventHandlerCallback);
593
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -0700594 mSuppressDefaultPolicy = suppressDefaultPolicy;
595
Dianne Hackborne17b4452018-01-10 13:15:40 -0800596 mPolicyFile = new AtomicFile(new File(systemDir, "netpolicy.xml"), "net-policy");
Svet Ganov16a16892015-04-16 10:32:04 -0700597
598 mAppOps = context.getSystemService(AppOpsManager.class);
Felipe Lemeb85a6372016-01-14 16:16:16 -0800599
Felipe Lemed17fda42016-04-29 11:12:45 -0700600 // Expose private service for system components to use.
601 LocalServices.addService(NetworkPolicyManagerInternal.class,
602 new NetworkPolicyManagerInternalImpl());
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700603 }
604
605 public void bindConnectivityManager(IConnectivityManager connManager) {
606 mConnManager = checkNotNull(connManager, "missing IConnectivityManager");
Jeff Sharkeya4620792011-05-20 15:29:23 -0700607 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -0700608
Felipe Lemef0823852016-06-08 13:43:08 -0700609 void updatePowerSaveWhitelistUL() {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700610 try {
Dianne Hackborn4a503b12015-08-06 22:19:06 -0700611 int[] whitelist = mDeviceIdleController.getAppIdWhitelistExceptIdle();
612 mPowerSaveWhitelistExceptIdleAppIds.clear();
613 if (whitelist != null) {
614 for (int uid : whitelist) {
615 mPowerSaveWhitelistExceptIdleAppIds.put(uid, true);
616 }
617 }
618 whitelist = mDeviceIdleController.getAppIdWhitelist();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700619 mPowerSaveWhitelistAppIds.clear();
620 if (whitelist != null) {
621 for (int uid : whitelist) {
622 mPowerSaveWhitelistAppIds.put(uid, true);
623 }
624 }
625 } catch (RemoteException e) {
626 }
627 }
628
Felipe Lemea9505cc2016-02-26 10:28:41 -0800629 /**
630 * Whitelists pre-defined apps for restrict background, but only if the user didn't already
631 * revoke the whitelist.
632 *
Felipe Leme46b451f2016-08-19 08:46:17 -0700633 * @return whether any uid has been whitelisted.
Felipe Lemea9505cc2016-02-26 10:28:41 -0800634 */
Felipe Lemef0823852016-06-08 13:43:08 -0700635 boolean addDefaultRestrictBackgroundWhitelistUidsUL() {
Felipe Lemea9505cc2016-02-26 10:28:41 -0800636 final List<UserInfo> users = mUserManager.getUsers();
637 final int numberUsers = users.size();
638
Felipe Lemea110eec2016-04-29 09:58:06 -0700639 boolean changed = false;
640 for (int i = 0; i < numberUsers; i++) {
641 final UserInfo user = users.get(i);
Felipe Lemef0823852016-06-08 13:43:08 -0700642 changed = addDefaultRestrictBackgroundWhitelistUidsUL(user.id) || changed;
Felipe Lemea110eec2016-04-29 09:58:06 -0700643 }
644 return changed;
645 }
646
Felipe Lemef0823852016-06-08 13:43:08 -0700647 private boolean addDefaultRestrictBackgroundWhitelistUidsUL(int userId) {
Felipe Lemea110eec2016-04-29 09:58:06 -0700648 final SystemConfig sysConfig = SystemConfig.getInstance();
649 final PackageManager pm = mContext.getPackageManager();
Felipe Lemea9505cc2016-02-26 10:28:41 -0800650 final ArraySet<String> allowDataUsage = sysConfig.getAllowInDataUsageSave();
651 boolean changed = false;
652 for (int i = 0; i < allowDataUsage.size(); i++) {
653 final String pkg = allowDataUsage.valueAt(i);
654 if (LOGD)
Felipe Lemea110eec2016-04-29 09:58:06 -0700655 Slog.d(TAG, "checking restricted background whitelisting for package " + pkg
656 + " and user " + userId);
Felipe Lemea9505cc2016-02-26 10:28:41 -0800657 final ApplicationInfo app;
658 try {
Felipe Lemea110eec2016-04-29 09:58:06 -0700659 app = pm.getApplicationInfoAsUser(pkg, PackageManager.MATCH_SYSTEM_ONLY, userId);
Felipe Lemea9505cc2016-02-26 10:28:41 -0800660 } catch (PackageManager.NameNotFoundException e) {
Felipe Lemea1252b22016-08-31 08:47:50 -0700661 if (LOGD) Slog.d(TAG, "No ApplicationInfo for package " + pkg);
662 // Ignore it - some apps on allow-in-data-usage-save are optional.
Felipe Lemea9505cc2016-02-26 10:28:41 -0800663 continue;
664 }
665 if (!app.isPrivilegedApp()) {
Felipe Lemea1252b22016-08-31 08:47:50 -0700666 Slog.e(TAG, "addDefaultRestrictBackgroundWhitelistUidsUL(): "
667 + "skipping non-privileged app " + pkg);
Felipe Lemea9505cc2016-02-26 10:28:41 -0800668 continue;
669 }
Felipe Lemea110eec2016-04-29 09:58:06 -0700670 final int uid = UserHandle.getUid(userId, app.uid);
671 mDefaultRestrictBackgroundWhitelistUids.append(uid, true);
672 if (LOGD)
673 Slog.d(TAG, "Adding uid " + uid + " (user " + userId + ") to default restricted "
674 + "background whitelist. Revoked status: "
Felipe Lemea9505cc2016-02-26 10:28:41 -0800675 + mRestrictBackgroundWhitelistRevokedUids.get(uid));
Felipe Lemea110eec2016-04-29 09:58:06 -0700676 if (!mRestrictBackgroundWhitelistRevokedUids.get(uid)) {
Felipe Lemea1252b22016-08-31 08:47:50 -0700677 if (LOGD)
678 Slog.d(TAG, "adding default package " + pkg + " (uid " + uid + " for user "
679 + userId + ") to restrict background whitelist");
Felipe Leme46b451f2016-08-19 08:46:17 -0700680 setUidPolicyUncheckedUL(uid, POLICY_ALLOW_METERED_BACKGROUND, false);
Felipe Lemea110eec2016-04-29 09:58:06 -0700681 changed = true;
Felipe Lemea9505cc2016-02-26 10:28:41 -0800682 }
683 }
684 return changed;
685 }
686
Fyodor Kupolov311b9fa2016-12-02 16:24:35 -0800687 private void initService(CountDownLatch initCompleteSignal) {
Felipe Leme873a83a2016-09-07 11:34:10 -0700688 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "systemReady");
Fyodor Kupolov311b9fa2016-12-02 16:24:35 -0800689 final int oldPriority = Process.getThreadPriority(Process.myTid());
Felipe Leme873a83a2016-09-07 11:34:10 -0700690 try {
Fyodor Kupolov311b9fa2016-12-02 16:24:35 -0800691 // Boost thread's priority during system server init
692 Process.setThreadPriority(Process.THREAD_PRIORITY_FOREGROUND);
Felipe Leme873a83a2016-09-07 11:34:10 -0700693 if (!isBandwidthControlEnabled()) {
694 Slog.w(TAG, "bandwidth controls disabled, unable to enforce policy");
695 return;
696 }
Jeff Sharkey8c1dc722012-05-04 14:49:37 -0700697
Felipe Leme873a83a2016-09-07 11:34:10 -0700698 mUsageStats = LocalServices.getService(UsageStatsManagerInternal.class);
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700699 mNetworkStats = LocalServices.getService(NetworkStatsManagerInternal.class);
Amith Yamasani15e472352015-04-24 19:06:07 -0700700
Felipe Leme873a83a2016-09-07 11:34:10 -0700701 synchronized (mUidRulesFirstLock) {
702 synchronized (mNetworkPoliciesSecondLock) {
703 updatePowerSaveWhitelistUL();
704 mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
705 mPowerManagerInternal.registerLowPowerModeObserver(
706 new PowerManagerInternal.LowPowerModeListener() {
jackqdyulei455e90a2017-02-09 15:29:16 -0800707 @Override
708 public int getServiceType() {
709 return ServiceType.NETWORK_FIREWALL;
Felipe Leme873a83a2016-09-07 11:34:10 -0700710 }
jackqdyulei455e90a2017-02-09 15:29:16 -0800711
712 @Override
713 public void onLowPowerModeChanged(PowerSaveState result) {
714 final boolean enabled = result.batterySaverEnabled;
jackqdyulei29c82ab2017-03-10 14:09:16 -0800715 if (LOGD) {
716 Slog.d(TAG, "onLowPowerModeChanged(" + enabled + ")");
717 }
jackqdyulei455e90a2017-02-09 15:29:16 -0800718 synchronized (mUidRulesFirstLock) {
719 if (mRestrictPower != enabled) {
720 mRestrictPower = enabled;
721 updateRulesForRestrictPowerUL();
722 }
723 }
724 }
jackqdyulei29c82ab2017-03-10 14:09:16 -0800725 });
jackqdyulei455e90a2017-02-09 15:29:16 -0800726 mRestrictPower = mPowerManagerInternal.getLowPowerState(
727 ServiceType.NETWORK_FIREWALL).batterySaverEnabled;
Felipe Leme873a83a2016-09-07 11:34:10 -0700728
729 mSystemReady = true;
730
Sudheer Shankac53c47f2018-01-16 12:01:00 -0800731 waitForAdminData();
732
Felipe Leme873a83a2016-09-07 11:34:10 -0700733 // read policy from disk
734 readPolicyAL();
735
jackqdyulei29c82ab2017-03-10 14:09:16 -0800736 // Update the restrictBackground if battery saver is turned on
Sudheer Shanka543339f2017-07-28 15:18:07 -0700737 mRestrictBackgroundBeforeBsm = mLoadedRestrictBackground;
jackqdyulei29c82ab2017-03-10 14:09:16 -0800738 mRestrictBackgroundPowerState = mPowerManagerInternal
739 .getLowPowerState(ServiceType.DATA_SAVER);
740 final boolean localRestrictBackground =
741 mRestrictBackgroundPowerState.batterySaverEnabled;
Sudheer Shanka543339f2017-07-28 15:18:07 -0700742 if (localRestrictBackground && !mLoadedRestrictBackground) {
743 mLoadedRestrictBackground = true;
jackqdyulei29c82ab2017-03-10 14:09:16 -0800744 }
745 mPowerManagerInternal.registerLowPowerModeObserver(
746 new PowerManagerInternal.LowPowerModeListener() {
747 @Override
748 public int getServiceType() {
749 return ServiceType.DATA_SAVER;
750 }
751
752 @Override
753 public void onLowPowerModeChanged(PowerSaveState result) {
754 synchronized (mUidRulesFirstLock) {
755 updateRestrictBackgroundByLowPowerModeUL(result);
756 }
757 }
758 });
759
Felipe Leme873a83a2016-09-07 11:34:10 -0700760 if (addDefaultRestrictBackgroundWhitelistUidsUL()) {
761 writePolicyAL();
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700762 }
Felipe Lemef0823852016-06-08 13:43:08 -0700763
Sudheer Shanka543339f2017-07-28 15:18:07 -0700764 setRestrictBackgroundUL(mLoadedRestrictBackground);
Felipe Leme873a83a2016-09-07 11:34:10 -0700765 updateRulesForGlobalChangeAL(false);
766 updateNotificationsNL();
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -0700767 }
Felipe Lemea9505cc2016-02-26 10:28:41 -0800768 }
Felipe Leme873a83a2016-09-07 11:34:10 -0700769
Sudheer Shankae7361852017-03-07 11:51:46 -0800770 mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
Felipe Leme873a83a2016-09-07 11:34:10 -0700771 try {
772 mActivityManager.registerUidObserver(mUidObserver,
Sudheer Shankac9d94072017-02-22 22:13:55 +0000773 ActivityManager.UID_OBSERVER_PROCSTATE|ActivityManager.UID_OBSERVER_GONE,
Dianne Hackborn5614bf52016-11-07 17:26:41 -0800774 ActivityManager.PROCESS_STATE_UNKNOWN, null);
Felipe Leme873a83a2016-09-07 11:34:10 -0700775 mNetworkManager.registerObserver(mAlertObserver);
776 } catch (RemoteException e) {
777 // ignored; both services live in system_server
778 }
779
780 // listen for changes to power save whitelist
781 final IntentFilter whitelistFilter = new IntentFilter(
782 PowerManager.ACTION_POWER_SAVE_WHITELIST_CHANGED);
783 mContext.registerReceiver(mPowerSaveWhitelistReceiver, whitelistFilter, null, mHandler);
784
Felipe Leme873a83a2016-09-07 11:34:10 -0700785 // watch for network interfaces to be claimed
786 final IntentFilter connFilter = new IntentFilter(CONNECTIVITY_ACTION);
787 mContext.registerReceiver(mConnReceiver, connFilter, CONNECTIVITY_INTERNAL, mHandler);
788
789 // listen for package changes to update policy
790 final IntentFilter packageFilter = new IntentFilter();
791 packageFilter.addAction(ACTION_PACKAGE_ADDED);
792 packageFilter.addDataScheme("package");
793 mContext.registerReceiver(mPackageReceiver, packageFilter, null, mHandler);
794
795 // listen for UID changes to update policy
796 mContext.registerReceiver(
797 mUidRemovedReceiver, new IntentFilter(ACTION_UID_REMOVED), null, mHandler);
798
799 // listen for user changes to update policy
800 final IntentFilter userFilter = new IntentFilter();
801 userFilter.addAction(ACTION_USER_ADDED);
802 userFilter.addAction(ACTION_USER_REMOVED);
803 mContext.registerReceiver(mUserReceiver, userFilter, null, mHandler);
804
805 // listen for stats update events
806 final IntentFilter statsFilter = new IntentFilter(ACTION_NETWORK_STATS_UPDATED);
807 mContext.registerReceiver(
808 mStatsReceiver, statsFilter, READ_NETWORK_USAGE_HISTORY, mHandler);
809
810 // listen for restrict background changes from notifications
811 final IntentFilter allowFilter = new IntentFilter(ACTION_ALLOW_BACKGROUND);
812 mContext.registerReceiver(mAllowReceiver, allowFilter, MANAGE_NETWORK_POLICY, mHandler);
813
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -0700814 // Listen for snooze from notifications
815 mContext.registerReceiver(mSnoozeReceiver,
816 new IntentFilter(ACTION_SNOOZE_WARNING), MANAGE_NETWORK_POLICY, mHandler);
817 mContext.registerReceiver(mSnoozeReceiver,
818 new IntentFilter(ACTION_SNOOZE_RAPID), MANAGE_NETWORK_POLICY, mHandler);
Felipe Leme873a83a2016-09-07 11:34:10 -0700819
Jeff Sharkey43d2a172017-07-12 10:50:42 -0600820 // listen for configured wifi networks to be loaded
821 final IntentFilter wifiFilter =
822 new IntentFilter(WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION);
823 mContext.registerReceiver(mWifiReceiver, wifiFilter, null, mHandler);
Felipe Leme873a83a2016-09-07 11:34:10 -0700824
Ammar Aijazi6ce48e22017-03-28 15:43:22 -0700825 // listen for carrier config changes to update data cycle information
826 final IntentFilter carrierConfigFilter = new IntentFilter(
827 ACTION_CARRIER_CONFIG_CHANGED);
828 mContext.registerReceiver(mCarrierConfigReceiver, carrierConfigFilter, null, mHandler);
829
Jeff Sharkeyb43a2922017-09-13 17:30:45 -0600830 // listen for meteredness changes
831 mContext.getSystemService(ConnectivityManager.class).registerNetworkCallback(
832 new NetworkRequest.Builder().build(), mNetworkCallback);
833
Felipe Leme873a83a2016-09-07 11:34:10 -0700834 mUsageStats.addAppIdleStateChangeListener(new AppIdleStateChangeListener());
Fyodor Kupolov311b9fa2016-12-02 16:24:35 -0800835 // tell systemReady() that the service has been initialized
836 initCompleteSignal.countDown();
Felipe Leme873a83a2016-09-07 11:34:10 -0700837 } finally {
Fyodor Kupolov311b9fa2016-12-02 16:24:35 -0800838 // Restore the default priority after init is done
839 Process.setThreadPriority(oldPriority);
Felipe Leme873a83a2016-09-07 11:34:10 -0700840 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700841 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -0700842 }
843
Fyodor Kupolov311b9fa2016-12-02 16:24:35 -0800844 public CountDownLatch networkScoreAndNetworkManagementServiceReady() {
845 final CountDownLatch initCompleteSignal = new CountDownLatch(1);
846 mHandler.post(() -> initService(initCompleteSignal));
847 return initCompleteSignal;
848 }
849
850 public void systemReady(CountDownLatch initCompleteSignal) {
851 // wait for initService to complete
852 try {
853 if (!initCompleteSignal.await(30, TimeUnit.SECONDS)) {
854 throw new IllegalStateException("Service " + TAG +" init timeout");
855 }
856 } catch (InterruptedException e) {
857 Thread.currentThread().interrupt();
858 throw new IllegalStateException("Service " + TAG + " init interrupted", e);
859 }
860 }
861
Sudheer Shankac9d94072017-02-22 22:13:55 +0000862 final private IUidObserver mUidObserver = new IUidObserver.Stub() {
Dianne Hackborn3e99f652017-07-05 16:33:56 -0700863 @Override public void onUidStateChanged(int uid, int procState, long procStateSeq) {
Makoto Onuki8e777332017-03-28 11:25:47 -0700864 mUidEventHandler.obtainMessage(UID_MSG_STATE_CHANGED,
865 uid, procState, procStateSeq).sendToTarget();
Dianne Hackborna93c2c12012-05-31 15:29:36 -0700866 }
867
Dianne Hackborn3e99f652017-07-05 16:33:56 -0700868 @Override public void onUidGone(int uid, boolean disabled) {
Makoto Onuki8e777332017-03-28 11:25:47 -0700869 mUidEventHandler.obtainMessage(UID_MSG_GONE, uid, 0).sendToTarget();
Jeff Sharkeya4620792011-05-20 15:29:23 -0700870 }
Dianne Hackbornbef28fe2015-10-29 17:57:11 -0700871
Dianne Hackborn3e99f652017-07-05 16:33:56 -0700872 @Override public void onUidActive(int uid) {
Dianne Hackbornbef28fe2015-10-29 17:57:11 -0700873 }
874
Dianne Hackborn3e99f652017-07-05 16:33:56 -0700875 @Override public void onUidIdle(int uid, boolean disabled) {
876 }
877
878 @Override public void onUidCachedChanged(int uid, boolean cached) {
Dianne Hackbornbef28fe2015-10-29 17:57:11 -0700879 }
Jeff Sharkeya4620792011-05-20 15:29:23 -0700880 };
881
Dianne Hackbornfd854ee2015-07-13 18:00:37 -0700882 final private BroadcastReceiver mPowerSaveWhitelistReceiver = new BroadcastReceiver() {
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700883 @Override
884 public void onReceive(Context context, Intent intent) {
885 // on background handler thread, and POWER_SAVE_WHITELIST_CHANGED is protected
Felipe Lemef0823852016-06-08 13:43:08 -0700886 synchronized (mUidRulesFirstLock) {
887 updatePowerSaveWhitelistUL();
888 updateRulesForRestrictPowerUL();
Felipe Leme09700462016-09-08 09:33:48 -0700889 updateRulesForAppIdleUL();
Dianne Hackborn0b4daca2015-04-27 09:47:32 -0700890 }
891 }
892 };
893
Dianne Hackbornfd854ee2015-07-13 18:00:37 -0700894 final private BroadcastReceiver mPackageReceiver = new BroadcastReceiver() {
Jeff Sharkeyb09540f2011-06-19 01:08:12 -0700895 @Override
896 public void onReceive(Context context, Intent intent) {
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -0700897 // on background handler thread, and PACKAGE_ADDED is protected
Jeff Sharkey02e21d62011-07-17 15:53:33 -0700898
899 final String action = intent.getAction();
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -0700900 final int uid = intent.getIntExtra(EXTRA_UID, -1);
901 if (uid == -1) return;
Jeff Sharkey8a8b5812012-03-21 18:13:36 -0700902
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -0700903 if (ACTION_PACKAGE_ADDED.equals(action)) {
904 // update rules for UID, since it might be subject to
905 // global background data policy
906 if (LOGV) Slog.v(TAG, "ACTION_PACKAGE_ADDED for uid=" + uid);
Felipe Lemef0823852016-06-08 13:43:08 -0700907 synchronized (mUidRulesFirstLock) {
Felipe Leme03e95e22016-09-09 09:25:31 -0700908 updateRestrictionRulesForUidUL(uid);
Jeff Sharkey02e21d62011-07-17 15:53:33 -0700909 }
Jeff Sharkeyb09540f2011-06-19 01:08:12 -0700910 }
911 }
912 };
913
Dianne Hackbornfd854ee2015-07-13 18:00:37 -0700914 final private BroadcastReceiver mUidRemovedReceiver = new BroadcastReceiver() {
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -0700915 @Override
916 public void onReceive(Context context, Intent intent) {
917 // on background handler thread, and UID_REMOVED is protected
918
919 final int uid = intent.getIntExtra(EXTRA_UID, -1);
920 if (uid == -1) return;
921
922 // remove any policy and update rules to clean up
923 if (LOGV) Slog.v(TAG, "ACTION_UID_REMOVED for uid=" + uid);
Felipe Lemef0823852016-06-08 13:43:08 -0700924 synchronized (mUidRulesFirstLock) {
Felipe Leme03e95e22016-09-09 09:25:31 -0700925 onUidDeletedUL(uid);
Felipe Lemef0823852016-06-08 13:43:08 -0700926 synchronized (mNetworkPoliciesSecondLock) {
927 writePolicyAL();
928 }
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -0700929 }
930 }
931 };
932
Dianne Hackbornfd854ee2015-07-13 18:00:37 -0700933 final private BroadcastReceiver mUserReceiver = new BroadcastReceiver() {
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -0700934 @Override
935 public void onReceive(Context context, Intent intent) {
936 // on background handler thread, and USER_ADDED and USER_REMOVED
937 // broadcasts are protected
938
939 final String action = intent.getAction();
940 final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
941 if (userId == -1) return;
942
Amith Yamasani15e472352015-04-24 19:06:07 -0700943 switch (action) {
944 case ACTION_USER_REMOVED:
945 case ACTION_USER_ADDED:
Felipe Lemef0823852016-06-08 13:43:08 -0700946 synchronized (mUidRulesFirstLock) {
Fyodor Kupolova31c5912016-01-22 11:26:09 -0800947 // Remove any persistable state for the given user; both cleaning up after a
Amith Yamasani15e472352015-04-24 19:06:07 -0700948 // USER_REMOVED, and one last sanity check during USER_ADDED
Felipe Lemef0823852016-06-08 13:43:08 -0700949 removeUserStateUL(userId, true);
Sudheer Shanka04d61ae2018-01-17 12:16:57 -0800950 // Removing outside removeUserStateUL since that can also be called when
951 // user resets app preferences.
952 mMeteredRestrictedUids.remove(userId);
Felipe Lemea110eec2016-04-29 09:58:06 -0700953 if (action == ACTION_USER_ADDED) {
954 // Add apps that are whitelisted by default.
Felipe Lemef0823852016-06-08 13:43:08 -0700955 addDefaultRestrictBackgroundWhitelistUidsUL(userId);
Felipe Lemea110eec2016-04-29 09:58:06 -0700956 }
957 // Update global restrict for that user
Felipe Lemef0823852016-06-08 13:43:08 -0700958 synchronized (mNetworkPoliciesSecondLock) {
959 updateRulesForGlobalChangeAL(true);
960 }
Amith Yamasani15e472352015-04-24 19:06:07 -0700961 }
962 break;
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -0700963 }
964 }
965 };
966
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700967 /**
Jeff Sharkey497e4432011-06-14 17:27:29 -0700968 * Receiver that watches for {@link INetworkStatsService} updates, which we
969 * use to check against {@link NetworkPolicy#warningBytes}.
970 */
Dianne Hackbornfd854ee2015-07-13 18:00:37 -0700971 final private BroadcastReceiver mStatsReceiver = new BroadcastReceiver() {
Jeff Sharkey497e4432011-06-14 17:27:29 -0700972 @Override
973 public void onReceive(Context context, Intent intent) {
974 // on background handler thread, and verified
975 // READ_NETWORK_USAGE_HISTORY permission above.
976
Felipe Lemef0823852016-06-08 13:43:08 -0700977 synchronized (mNetworkPoliciesSecondLock) {
978 updateNetworkEnabledNL();
979 updateNotificationsNL();
Jeff Sharkey497e4432011-06-14 17:27:29 -0700980 }
981 }
982 };
983
984 /**
Jeff Sharkey3a844fc2011-08-16 14:37:57 -0700985 * Receiver that watches for {@link Notification} control of
986 * {@link #mRestrictBackground}.
987 */
Dianne Hackbornfd854ee2015-07-13 18:00:37 -0700988 final private BroadcastReceiver mAllowReceiver = new BroadcastReceiver() {
Jeff Sharkey3a844fc2011-08-16 14:37:57 -0700989 @Override
990 public void onReceive(Context context, Intent intent) {
991 // on background handler thread, and verified MANAGE_NETWORK_POLICY
992 // permission above.
993
994 setRestrictBackground(false);
995 }
996 };
997
998 /**
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -0800999 * Receiver that watches for {@link Notification} control of
1000 * {@link NetworkPolicy#lastWarningSnooze}.
1001 */
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001002 final private BroadcastReceiver mSnoozeReceiver = new BroadcastReceiver() {
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -08001003 @Override
1004 public void onReceive(Context context, Intent intent) {
1005 // on background handler thread, and verified MANAGE_NETWORK_POLICY
1006 // permission above.
1007
1008 final NetworkTemplate template = intent.getParcelableExtra(EXTRA_NETWORK_TEMPLATE);
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001009 if (ACTION_SNOOZE_WARNING.equals(intent.getAction())) {
1010 performSnooze(template, TYPE_WARNING);
1011 } else if (ACTION_SNOOZE_RAPID.equals(intent.getAction())) {
1012 performSnooze(template, TYPE_RAPID);
1013 }
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -08001014 }
1015 };
1016
1017 /**
Jeff Sharkey43d2a172017-07-12 10:50:42 -06001018 * Receiver that watches for {@link WifiConfiguration} to be loaded so that
Jeff Sharkey64c96ec2017-08-30 16:28:26 -06001019 * we can perform upgrade logic. After initial upgrade logic, it updates
1020 * {@link #mMeteredIfaces} based on configuration changes.
Jeff Sharkey9f6e4ba2012-04-19 23:01:08 -07001021 */
Jeff Sharkey43d2a172017-07-12 10:50:42 -06001022 final private BroadcastReceiver mWifiReceiver = new BroadcastReceiver() {
Jeff Sharkey9f6e4ba2012-04-19 23:01:08 -07001023 @Override
1024 public void onReceive(Context context, Intent intent) {
Hugo Benichi446c9c92017-04-10 09:41:10 +09001025 synchronized (mUidRulesFirstLock) {
1026 synchronized (mNetworkPoliciesSecondLock) {
Jeff Sharkey43d2a172017-07-12 10:50:42 -06001027 upgradeWifiMeteredOverrideAL();
Jeff Sharkeyb43a2922017-09-13 17:30:45 -06001028 }
1029 }
1030 // Only need to perform upgrade logic once
1031 mContext.unregisterReceiver(this);
1032 }
1033 };
1034
1035 private final NetworkCallback mNetworkCallback = new NetworkCallback() {
1036 @Override
1037 public void onCapabilitiesChanged(Network network,
1038 NetworkCapabilities networkCapabilities) {
1039 if (network == null || networkCapabilities == null) return;
1040
1041 synchronized (mNetworkPoliciesSecondLock) {
1042 final boolean oldMetered = mNetworkMetered.get(network.netId, false);
1043 final boolean newMetered = !networkCapabilities
1044 .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
1045
1046 if ((oldMetered != newMetered) || mNetworkMetered.indexOfKey(network.netId) < 0) {
Sudheer Shanka352dc572017-09-22 17:09:38 -07001047 mLogger.meterednessChanged(network.netId, newMetered);
Jeff Sharkeyb43a2922017-09-13 17:30:45 -06001048 mNetworkMetered.put(network.netId, newMetered);
Jeff Sharkey64c96ec2017-08-30 16:28:26 -06001049 updateNetworkRulesNL();
Jeff Sharkey9f6e4ba2012-04-19 23:01:08 -07001050 }
1051 }
1052 }
1053 };
1054
1055 /**
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001056 * Observer that watches for {@link INetworkManagementService} alerts.
1057 */
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07001058 final private INetworkManagementEventObserver mAlertObserver
1059 = new BaseNetworkObserver() {
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001060 @Override
1061 public void limitReached(String limitName, String iface) {
1062 // only someone like NMS should be calling us
1063 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1064
Jeff Sharkey7e25b0e2011-11-08 15:43:12 -08001065 if (!LIMIT_GLOBAL_ALERT.equals(limitName)) {
1066 mHandler.obtainMessage(MSG_LIMIT_REACHED, iface).sendToTarget();
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001067 }
1068 }
1069 };
1070
1071 /**
Jeff Sharkey497e4432011-06-14 17:27:29 -07001072 * Check {@link NetworkPolicy} against current {@link INetworkStatsService}
1073 * to show visible notifications as needed.
1074 */
Felipe Lemef0823852016-06-08 13:43:08 -07001075 void updateNotificationsNL() {
1076 if (LOGV) Slog.v(TAG, "updateNotificationsNL()");
Jeff Sharkey497e4432011-06-14 17:27:29 -07001077
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001078 // keep track of previously active notifications
Chris Wren193ae6b2017-03-31 15:17:11 -04001079 final ArraySet<NotificationId> beforeNotifs = new ArraySet<NotificationId>(mActiveNotifs);
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001080 mActiveNotifs.clear();
Jeff Sharkey497e4432011-06-14 17:27:29 -07001081
1082 // TODO: when switching to kernel notifications, compute next future
1083 // cycle boundary to recompute notifications.
1084
Jeff Sharkey02e21d62011-07-17 15:53:33 -07001085 // examine stats for each active policy
Jeff Sharkey9911a282018-02-14 22:29:11 -07001086 final long now = mClock.millis();
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -07001087 for (int i = mNetworkPolicy.size()-1; i >= 0; i--) {
1088 final NetworkPolicy policy = mNetworkPolicy.valueAt(i);
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001089 // ignore policies that aren't relevant to user
1090 if (!isTemplateRelevant(policy.template)) continue;
Jeff Sharkey8fc27e82012-04-04 20:40:58 -07001091 if (!policy.hasCycle()) continue;
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001092
Jeff Sharkey53313d72017-07-13 16:47:32 -06001093 final Pair<ZonedDateTime, ZonedDateTime> cycle = NetworkPolicyManager
1094 .cycleIterator(policy).next();
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001095 final long cycleStart = cycle.first.toInstant().toEpochMilli();
1096 final long cycleEnd = cycle.second.toInstant().toEpochMilli();
1097 final long totalBytes = getTotalBytes(policy.template, cycleStart, cycleEnd);
Jeff Sharkey497e4432011-06-14 17:27:29 -07001098
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001099 // Notify when data usage is over warning/limit
Jeff Sharkey50e7e512011-10-10 16:50:35 -07001100 if (policy.isOverLimit(totalBytes)) {
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001101 final boolean snoozedThisCycle = policy.lastLimitSnooze >= cycleStart;
1102 if (snoozedThisCycle) {
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001103 enqueueNotification(policy, TYPE_LIMIT_SNOOZED, totalBytes, null);
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001104 } else {
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001105 enqueueNotification(policy, TYPE_LIMIT, totalBytes, null);
Felipe Lemef0823852016-06-08 13:43:08 -07001106 notifyOverLimitNL(policy.template);
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001107 }
1108
Jeff Sharkey497e4432011-06-14 17:27:29 -07001109 } else {
Felipe Lemef0823852016-06-08 13:43:08 -07001110 notifyUnderLimitNL(policy.template);
Jeff Sharkey497e4432011-06-14 17:27:29 -07001111
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001112 final boolean snoozedThisCycle = policy.lastWarningSnooze >= cycleStart;
1113 if (policy.isOverWarning(totalBytes) && !snoozedThisCycle) {
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001114 enqueueNotification(policy, TYPE_WARNING, totalBytes, null);
Jeff Sharkey497e4432011-06-14 17:27:29 -07001115 }
1116 }
Jeff Sharkey02e21d62011-07-17 15:53:33 -07001117
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001118 // Warn if average usage over last 4 days is on track to blow pretty
1119 // far past the plan limits.
1120 if (policy.limitBytes != LIMIT_DISABLED) {
Jeff Sharkey2e471452018-01-19 18:02:47 +09001121 final long recentDuration = TimeUnit.DAYS.toMillis(4);
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001122 final long recentStart = now - recentDuration;
1123 final long recentEnd = now;
1124 final long recentBytes = getTotalBytes(policy.template, recentStart, recentEnd);
Jeff Sharkey2e471452018-01-19 18:02:47 +09001125
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001126 final long cycleDuration = cycleEnd - cycleStart;
Jeff Sharkey2e471452018-01-19 18:02:47 +09001127 final long projectedBytes = (recentBytes * cycleDuration) / recentDuration;
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001128 final long alertBytes = (policy.limitBytes * 3) / 2;
1129
1130 if (LOGD) {
1131 Slog.d(TAG, "Rapid usage considering recent " + recentBytes + " projected "
1132 + projectedBytes + " alert " + alertBytes);
1133 }
1134
1135 final boolean snoozedRecently = policy.lastRapidSnooze >= now
1136 - DateUtils.DAY_IN_MILLIS;
1137 if (projectedBytes > alertBytes && !snoozedRecently) {
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001138 enqueueNotification(policy, TYPE_RAPID, 0,
1139 findRapidBlame(policy.template, recentStart, recentEnd));
Jeff Sharkey2e471452018-01-19 18:02:47 +09001140 }
1141 }
1142 }
1143
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001144 // cancel stale notifications that we didn't renew above
Dianne Hackborn497175b2014-07-01 12:56:08 -07001145 for (int i = beforeNotifs.size()-1; i >= 0; i--) {
Chris Wren193ae6b2017-03-31 15:17:11 -04001146 final NotificationId notificationId = beforeNotifs.valueAt(i);
1147 if (!mActiveNotifs.contains(notificationId)) {
1148 cancelNotification(notificationId);
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001149 }
1150 }
1151 }
1152
1153 /**
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001154 * Attempt to find a specific app to blame for rapid data usage during the
1155 * given time period.
1156 */
1157 private @Nullable ApplicationInfo findRapidBlame(NetworkTemplate template,
1158 long start, long end) {
1159 long totalBytes = 0;
1160 long maxBytes = 0;
1161 int maxUid = 0;
1162
1163 final NetworkStats stats = getNetworkUidBytes(template, start, end);
1164 NetworkStats.Entry entry = null;
1165 for (int i = 0; i < stats.size(); i++) {
1166 entry = stats.getValues(i, entry);
1167 final long bytes = entry.rxBytes + entry.txBytes;
1168 totalBytes += bytes;
1169 if (bytes > maxBytes) {
1170 maxBytes = bytes;
1171 maxUid = entry.uid;
1172 }
1173 }
1174
1175 // Only point blame if the majority of usage was done by a single app.
1176 // TODO: support shared UIDs
1177 if (maxBytes > 0 && maxBytes > totalBytes / 2) {
1178 final String[] packageNames = mContext.getPackageManager().getPackagesForUid(maxUid);
Jeff Sharkeyd37154e2018-03-26 16:50:59 -06001179 if (packageNames != null && packageNames.length == 1) {
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001180 try {
1181 return mContext.getPackageManager().getApplicationInfo(packageNames[0],
1182 MATCH_ANY_USER | MATCH_DISABLED_COMPONENTS | MATCH_DIRECT_BOOT_AWARE
1183 | MATCH_DIRECT_BOOT_UNAWARE | MATCH_UNINSTALLED_PACKAGES);
1184 } catch (NameNotFoundException ignored) {
1185 }
1186 }
1187 }
1188
1189 return null;
1190 }
1191
1192 /**
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001193 * Test if given {@link NetworkTemplate} is relevant to user based on
Jeff Sharkey8fc27e82012-04-04 20:40:58 -07001194 * current device state, such as when
1195 * {@link TelephonyManager#getSubscriberId()} matches. This is regardless of
1196 * data connection status.
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001197 */
1198 private boolean isTemplateRelevant(NetworkTemplate template) {
Jeff Sharkey32566012014-12-02 18:30:14 -08001199 if (template.isMatchRuleMobile()) {
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001200 final TelephonyManager tele = mContext.getSystemService(TelephonyManager.class);
1201 final SubscriptionManager sub = mContext.getSystemService(SubscriptionManager.class);
Jeff Sharkey8fc27e82012-04-04 20:40:58 -07001202
Jeff Sharkey32566012014-12-02 18:30:14 -08001203 // Mobile template is relevant when any active subscriber matches
Jeff Sharkey2e471452018-01-19 18:02:47 +09001204 final int[] subIds = ArrayUtils.defeatNullable(sub.getActiveSubscriptionIdList());
Jeff Sharkey32566012014-12-02 18:30:14 -08001205 for (int subId : subIds) {
1206 final String subscriberId = tele.getSubscriberId(subId);
1207 final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE,
Lorenzo Colittid3e4a1e2018-01-19 01:12:04 +09001208 TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true,
1209 true);
Jeff Sharkey32566012014-12-02 18:30:14 -08001210 if (template.matches(probeIdent)) {
1211 return true;
Jeff Sharkey3a66cf32012-03-20 17:00:01 -07001212 }
Jeff Sharkey32566012014-12-02 18:30:14 -08001213 }
1214 return false;
1215 } else {
1216 return true;
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001217 }
Jeff Sharkey497e4432011-06-14 17:27:29 -07001218 }
1219
1220 /**
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001221 * Notify that given {@link NetworkTemplate} is over
1222 * {@link NetworkPolicy#limitBytes}, potentially showing dialog to user.
1223 */
Felipe Lemef0823852016-06-08 13:43:08 -07001224 private void notifyOverLimitNL(NetworkTemplate template) {
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001225 if (!mOverLimitNotified.contains(template)) {
Wei Liu546cb772016-07-21 16:19:01 -07001226 mContext.startActivity(buildNetworkOverLimitIntent(mContext.getResources(), template));
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001227 mOverLimitNotified.add(template);
1228 }
1229 }
1230
Felipe Lemef0823852016-06-08 13:43:08 -07001231 private void notifyUnderLimitNL(NetworkTemplate template) {
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001232 mOverLimitNotified.remove(template);
1233 }
1234
1235 /**
Jeff Sharkey497e4432011-06-14 17:27:29 -07001236 * Show notification for combined {@link NetworkPolicy} and specific type,
1237 * like {@link #TYPE_LIMIT}. Okay to call multiple times.
1238 */
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001239 private void enqueueNotification(NetworkPolicy policy, int type, long totalBytes,
1240 ApplicationInfo rapidBlame) {
Chris Wren193ae6b2017-03-31 15:17:11 -04001241 final NotificationId notificationId = new NotificationId(policy, type);
Geoffrey Pitschaf759c52017-02-15 09:35:38 -05001242 final Notification.Builder builder =
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001243 new Notification.Builder(mContext, SystemNotificationChannels.NETWORK_ALERTS);
Jeff Sharkey497e4432011-06-14 17:27:29 -07001244 builder.setOnlyAlertOnce(true);
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -08001245 builder.setWhen(0L);
Alan Viverette4a357cd2015-03-18 18:37:18 -07001246 builder.setColor(mContext.getColor(
Selim Cinek255dd042014-08-19 22:29:02 +02001247 com.android.internal.R.color.system_notification_accent_color));
Jeff Sharkey497e4432011-06-14 17:27:29 -07001248
1249 final Resources res = mContext.getResources();
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001250 final CharSequence title;
1251 final CharSequence body;
Jeff Sharkey497e4432011-06-14 17:27:29 -07001252 switch (type) {
1253 case TYPE_WARNING: {
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001254 title = res.getText(R.string.data_usage_warning_title);
1255 body = res.getString(R.string.data_usage_warning_body,
1256 Formatter.formatFileSize(mContext, totalBytes));
Jeff Sharkey497e4432011-06-14 17:27:29 -07001257
Jeff Sharkey50e7e512011-10-10 16:50:35 -07001258 builder.setSmallIcon(R.drawable.stat_notify_error);
Jeff Sharkey14711eb2011-06-15 10:29:17 -07001259
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -08001260 final Intent snoozeIntent = buildSnoozeWarningIntent(policy.template);
1261 builder.setDeleteIntent(PendingIntent.getBroadcast(
1262 mContext, 0, snoozeIntent, PendingIntent.FLAG_UPDATE_CURRENT));
1263
Wei Liu546cb772016-07-21 16:19:01 -07001264 final Intent viewIntent = buildViewDataUsageIntent(res, policy.template);
Jeff Sharkey14711eb2011-06-15 10:29:17 -07001265 builder.setContentIntent(PendingIntent.getActivity(
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -08001266 mContext, 0, viewIntent, PendingIntent.FLAG_UPDATE_CURRENT));
1267
Jeff Sharkey497e4432011-06-14 17:27:29 -07001268 break;
1269 }
1270 case TYPE_LIMIT: {
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -07001271 switch (policy.template.getMatchRule()) {
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001272 case MATCH_MOBILE:
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001273 title = res.getText(R.string.data_usage_mobile_limit_title);
Jeff Sharkey497e4432011-06-14 17:27:29 -07001274 break;
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001275 case MATCH_WIFI:
1276 title = res.getText(R.string.data_usage_wifi_limit_title);
1277 break;
1278 default:
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001279 return;
Jeff Sharkey497e4432011-06-14 17:27:29 -07001280 }
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001281 body = res.getText(R.string.data_usage_limit_body);
Jeff Sharkey497e4432011-06-14 17:27:29 -07001282
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -08001283 builder.setOngoing(true);
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001284 builder.setSmallIcon(R.drawable.stat_notify_disabled_data);
Jeff Sharkey14711eb2011-06-15 10:29:17 -07001285
Wei Liu546cb772016-07-21 16:19:01 -07001286 final Intent intent = buildNetworkOverLimitIntent(res, policy.template);
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001287 builder.setContentIntent(PendingIntent.getActivity(
1288 mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT));
1289 break;
1290 }
1291 case TYPE_LIMIT_SNOOZED: {
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001292 switch (policy.template.getMatchRule()) {
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001293 case MATCH_MOBILE:
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001294 title = res.getText(R.string.data_usage_mobile_limit_snoozed_title);
1295 break;
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001296 case MATCH_WIFI:
1297 title = res.getText(R.string.data_usage_wifi_limit_snoozed_title);
1298 break;
1299 default:
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001300 return;
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001301 }
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001302 final long overBytes = totalBytes - policy.limitBytes;
1303 body = res.getString(R.string.data_usage_limit_snoozed_body,
1304 Formatter.formatFileSize(mContext, overBytes));
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001305
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -08001306 builder.setOngoing(true);
Jeff Sharkey50e7e512011-10-10 16:50:35 -07001307 builder.setSmallIcon(R.drawable.stat_notify_error);
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001308 builder.setChannelId(SystemNotificationChannels.NETWORK_STATUS);
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001309
Wei Liu546cb772016-07-21 16:19:01 -07001310 final Intent intent = buildViewDataUsageIntent(res, policy.template);
Jeff Sharkey14711eb2011-06-15 10:29:17 -07001311 builder.setContentIntent(PendingIntent.getActivity(
1312 mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT));
Jeff Sharkey497e4432011-06-14 17:27:29 -07001313 break;
1314 }
Jeff Sharkey2e471452018-01-19 18:02:47 +09001315 case TYPE_RAPID: {
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001316 title = res.getText(R.string.data_usage_rapid_title);
1317 if (rapidBlame != null) {
1318 body = res.getString(R.string.data_usage_rapid_app_body,
1319 rapidBlame.loadLabel(mContext.getPackageManager()));
1320 } else {
1321 body = res.getString(R.string.data_usage_rapid_body);
1322 }
Jeff Sharkey2e471452018-01-19 18:02:47 +09001323
Jeff Sharkey2e471452018-01-19 18:02:47 +09001324 builder.setSmallIcon(R.drawable.stat_notify_error);
Jeff Sharkey2e471452018-01-19 18:02:47 +09001325
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001326 final Intent snoozeIntent = buildSnoozeRapidIntent(policy.template);
1327 builder.setDeleteIntent(PendingIntent.getBroadcast(
1328 mContext, 0, snoozeIntent, PendingIntent.FLAG_UPDATE_CURRENT));
1329
1330 final Intent viewIntent = buildViewDataUsageIntent(res, policy.template);
Jeff Sharkey2e471452018-01-19 18:02:47 +09001331 builder.setContentIntent(PendingIntent.getActivity(
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001332 mContext, 0, viewIntent, PendingIntent.FLAG_UPDATE_CURRENT));
Jeff Sharkey2e471452018-01-19 18:02:47 +09001333 break;
1334 }
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001335 default: {
1336 return;
1337 }
Jeff Sharkey497e4432011-06-14 17:27:29 -07001338 }
1339
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001340 builder.setTicker(title);
1341 builder.setContentTitle(title);
1342 builder.setContentText(body);
1343 builder.setStyle(new Notification.BigTextStyle().bigText(body));
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001344
1345 mContext.getSystemService(NotificationManager.class).notifyAsUser(notificationId.getTag(),
1346 notificationId.getId(), builder.build(), UserHandle.ALL);
1347 mActiveNotifs.add(notificationId);
Jeff Sharkey497e4432011-06-14 17:27:29 -07001348 }
1349
Chris Wren193ae6b2017-03-31 15:17:11 -04001350 private void cancelNotification(NotificationId notificationId) {
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001351 mContext.getSystemService(NotificationManager.class).cancel(notificationId.getTag(),
1352 notificationId.getId());
Jeff Sharkey497e4432011-06-14 17:27:29 -07001353 }
1354
1355 /**
Jeff Sharkey21c9c452011-06-07 12:26:43 -07001356 * Receiver that watches for {@link IConnectivityManager} to claim network
Jeff Sharkey22c055e2011-06-12 21:13:51 -07001357 * interfaces. Used to apply {@link NetworkPolicy} to matching networks.
Jeff Sharkey21c9c452011-06-07 12:26:43 -07001358 */
Jeff Sharkeyb09540f2011-06-19 01:08:12 -07001359 private BroadcastReceiver mConnReceiver = new BroadcastReceiver() {
Jeff Sharkey21c9c452011-06-07 12:26:43 -07001360 @Override
1361 public void onReceive(Context context, Intent intent) {
1362 // on background handler thread, and verified CONNECTIVITY_INTERNAL
1363 // permission above.
Jeff Sharkey684c54a2011-11-16 17:46:30 -08001364
Hugo Benichi446c9c92017-04-10 09:41:10 +09001365 synchronized (mUidRulesFirstLock) {
1366 synchronized (mNetworkPoliciesSecondLock) {
1367 ensureActiveMobilePolicyAL();
1368 normalizePoliciesNL();
1369 updateNetworkEnabledNL();
1370 updateNetworkRulesNL();
1371 updateNotificationsNL();
1372 }
Jeff Sharkey21c9c452011-06-07 12:26:43 -07001373 }
1374 }
1375 };
1376
Jeff Sharkey2e471452018-01-19 18:02:47 +09001377 @VisibleForTesting
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001378 public void updateNetworks() throws InterruptedException {
Jeff Sharkey2e471452018-01-19 18:02:47 +09001379 mConnReceiver.onReceive(null, null);
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001380 final CountDownLatch latch = new CountDownLatch(1);
1381 mHandler.post(() -> {
1382 latch.countDown();
1383 });
1384 latch.await(5, TimeUnit.SECONDS);
Jeff Sharkey2e471452018-01-19 18:02:47 +09001385 }
1386
Jeff Sharkey21c9c452011-06-07 12:26:43 -07001387 /**
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07001388 * Update mobile policies with data cycle information from {@link CarrierConfigManager}
1389 * if necessary.
1390 *
1391 * @param subId that has its associated NetworkPolicy updated if necessary
1392 * @return if any policies were updated
1393 */
Jeff Sharkey0f2910c2017-07-30 16:52:51 -06001394 private boolean maybeUpdateMobilePolicyCycleAL(int subId) {
1395 if (LOGV) Slog.v(TAG, "maybeUpdateMobilePolicyCycleAL()");
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07001396
1397 boolean policyUpdated = false;
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001398 final String subscriberId = mContext.getSystemService(TelephonyManager.class)
1399 .getSubscriberId(subId);
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07001400
1401 // find and update the mobile NetworkPolicy for this subscriber id
1402 final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE,
Lorenzo Colittid3e4a1e2018-01-19 01:12:04 +09001403 TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true, true);
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07001404 for (int i = mNetworkPolicy.size() - 1; i >= 0; i--) {
1405 final NetworkTemplate template = mNetworkPolicy.keyAt(i);
1406 if (template.matches(probeIdent)) {
Jeff Sharkey0f2910c2017-07-30 16:52:51 -06001407 final NetworkPolicy policy = mNetworkPolicy.valueAt(i);
1408 policyUpdated |= updateDefaultMobilePolicyAL(subId, policy);
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07001409 }
1410 }
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07001411 return policyUpdated;
1412 }
1413
1414 /**
1415 * Returns the cycle day that should be used for a mobile NetworkPolicy.
1416 *
1417 * It attempts to get an appropriate cycle day from the passed in CarrierConfig. If it's unable
1418 * to do so, it returns the fallback value.
1419 *
1420 * @param config The CarrierConfig to read the value from.
1421 * @param fallbackCycleDay to return if the CarrierConfig can't be read.
1422 * @return cycleDay to use in the mobile NetworkPolicy.
1423 */
1424 @VisibleForTesting
1425 public int getCycleDayFromCarrierConfig(@Nullable PersistableBundle config,
1426 int fallbackCycleDay) {
1427 if (config == null) {
1428 return fallbackCycleDay;
1429 }
1430 int cycleDay =
1431 config.getInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT);
1432 if (cycleDay == DATA_CYCLE_USE_PLATFORM_DEFAULT) {
1433 return fallbackCycleDay;
1434 }
1435 // validate cycleDay value
1436 final Calendar cal = Calendar.getInstance();
1437 if (cycleDay < cal.getMinimum(Calendar.DAY_OF_MONTH) ||
1438 cycleDay > cal.getMaximum(Calendar.DAY_OF_MONTH)) {
1439 Slog.e(TAG, "Invalid date in "
1440 + "CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT: " + cycleDay);
1441 return fallbackCycleDay;
1442 }
1443 return cycleDay;
1444 }
1445
1446 /**
1447 * Returns the warning bytes that should be used for a mobile NetworkPolicy.
1448 *
1449 * It attempts to get an appropriate value from the passed in CarrierConfig. If it's unable
1450 * to do so, it returns the fallback value.
1451 *
1452 * @param config The CarrierConfig to read the value from.
1453 * @param fallbackWarningBytes to return if the CarrierConfig can't be read.
1454 * @return warningBytes to use in the mobile NetworkPolicy.
1455 */
1456 @VisibleForTesting
1457 public long getWarningBytesFromCarrierConfig(@Nullable PersistableBundle config,
1458 long fallbackWarningBytes) {
1459 if (config == null) {
1460 return fallbackWarningBytes;
1461 }
1462 long warningBytes =
1463 config.getLong(CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG);
1464
1465 if (warningBytes == DATA_CYCLE_THRESHOLD_DISABLED) {
1466 return WARNING_DISABLED;
1467 } else if (warningBytes == DATA_CYCLE_USE_PLATFORM_DEFAULT) {
1468 return getPlatformDefaultWarningBytes();
1469 } else if (warningBytes < 0) {
1470 Slog.e(TAG, "Invalid value in "
1471 + "CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG; expected a "
1472 + "non-negative value but got: " + warningBytes);
1473 return fallbackWarningBytes;
1474 }
1475
1476 return warningBytes;
1477 }
1478
1479 /**
1480 * Returns the limit bytes that should be used for a mobile NetworkPolicy.
1481 *
1482 * It attempts to get an appropriate value from the passed in CarrierConfig. If it's unable
1483 * to do so, it returns the fallback value.
1484 *
1485 * @param config The CarrierConfig to read the value from.
1486 * @param fallbackLimitBytes to return if the CarrierConfig can't be read.
1487 * @return limitBytes to use in the mobile NetworkPolicy.
1488 */
1489 @VisibleForTesting
1490 public long getLimitBytesFromCarrierConfig(@Nullable PersistableBundle config,
1491 long fallbackLimitBytes) {
1492 if (config == null) {
1493 return fallbackLimitBytes;
1494 }
1495 long limitBytes =
1496 config.getLong(CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG);
1497
1498 if (limitBytes == DATA_CYCLE_THRESHOLD_DISABLED) {
1499 return LIMIT_DISABLED;
1500 } else if (limitBytes == DATA_CYCLE_USE_PLATFORM_DEFAULT) {
1501 return getPlatformDefaultLimitBytes();
1502 } else if (limitBytes < 0) {
1503 Slog.e(TAG, "Invalid value in "
1504 + "CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG; expected a "
1505 + "non-negative value but got: " + limitBytes);
1506 return fallbackLimitBytes;
1507 }
1508 return limitBytes;
1509 }
1510
1511 /**
1512 * Receiver that watches for {@link CarrierConfigManager} to be changed.
1513 */
1514 private BroadcastReceiver mCarrierConfigReceiver = new BroadcastReceiver() {
1515 @Override
1516 public void onReceive(Context context, Intent intent) {
1517 // No need to do a permission check, because the ACTION_CARRIER_CONFIG_CHANGED
1518 // broadcast is protected and can't be spoofed. Runs on a background handler thread.
1519
1520 if (!intent.hasExtra(PhoneConstants.SUBSCRIPTION_KEY)) {
1521 return;
1522 }
1523 final int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY, -1);
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001524 final TelephonyManager tele = mContext.getSystemService(TelephonyManager.class);
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07001525 final String subscriberId = tele.getSubscriberId(subId);
1526
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07001527 synchronized (mUidRulesFirstLock) {
1528 synchronized (mNetworkPoliciesSecondLock) {
Hugo Benichi446c9c92017-04-10 09:41:10 +09001529 final boolean added = ensureActiveMobilePolicyAL(subId, subscriberId);
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07001530 if (added) return;
Jeff Sharkey0f2910c2017-07-30 16:52:51 -06001531 final boolean updated = maybeUpdateMobilePolicyCycleAL(subId);
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07001532 if (!updated) return;
1533 // update network and notification rules, as the data cycle changed and it's
1534 // possible that we should be triggering warnings/limits now
1535 handleNetworkPoliciesUpdateAL(true);
1536 }
1537 }
1538 }
1539 };
1540
1541 /**
1542 * Handles all tasks that need to be run after a new network policy has been set, or an existing
1543 * one has been updated.
1544 *
1545 * @param shouldNormalizePolicies true iff network policies need to be normalized after the
1546 * update.
1547 */
1548 void handleNetworkPoliciesUpdateAL(boolean shouldNormalizePolicies) {
1549 if (shouldNormalizePolicies) {
1550 normalizePoliciesNL();
1551 }
1552 updateNetworkEnabledNL();
1553 updateNetworkRulesNL();
1554 updateNotificationsNL();
1555 writePolicyAL();
1556 }
1557
1558 /**
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001559 * Proactively control network data connections when they exceed
1560 * {@link NetworkPolicy#limitBytes}.
1561 */
Felipe Lemef0823852016-06-08 13:43:08 -07001562 void updateNetworkEnabledNL() {
1563 if (LOGV) Slog.v(TAG, "updateNetworkEnabledNL()");
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001564
1565 // TODO: reset any policy-disabled networks when any policy is removed
1566 // completely, which is currently rare case.
1567
Makoto Onuki49392d32018-04-11 13:51:02 -07001568 final long startTime = mStatLogger.getTime();
1569
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -07001570 for (int i = mNetworkPolicy.size()-1; i >= 0; i--) {
1571 final NetworkPolicy policy = mNetworkPolicy.valueAt(i);
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001572 // shortcut when policy has no limit
Jeff Sharkey8fc27e82012-04-04 20:40:58 -07001573 if (policy.limitBytes == LIMIT_DISABLED || !policy.hasCycle()) {
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001574 setNetworkTemplateEnabled(policy.template, true);
1575 continue;
1576 }
1577
Jeff Sharkey53313d72017-07-13 16:47:32 -06001578 final Pair<ZonedDateTime, ZonedDateTime> cycle = NetworkPolicyManager
1579 .cycleIterator(policy).next();
1580 final long start = cycle.first.toInstant().toEpochMilli();
1581 final long end = cycle.second.toInstant().toEpochMilli();
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001582 final long totalBytes = getTotalBytes(policy.template, start, end);
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001583
1584 // disable data connection when over limit and not snoozed
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -08001585 final boolean overLimitWithoutSnooze = policy.isOverLimit(totalBytes)
1586 && policy.lastLimitSnooze < start;
1587 final boolean networkEnabled = !overLimitWithoutSnooze;
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001588
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -08001589 setNetworkTemplateEnabled(policy.template, networkEnabled);
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001590 }
Makoto Onuki49392d32018-04-11 13:51:02 -07001591
1592 mStatLogger.logDurationStat(Stats.UPDATE_NETWORK_ENABLED, startTime);
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001593 }
1594
1595 /**
Jeff Sharkey32566012014-12-02 18:30:14 -08001596 * Proactively disable networks that match the given
1597 * {@link NetworkTemplate}.
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001598 */
1599 private void setNetworkTemplateEnabled(NetworkTemplate template, boolean enabled) {
Makoto Onuki3f1bf5f2018-04-04 15:29:00 -07001600 // Don't call setNetworkTemplateEnabledInner() directly because we may have a lock
1601 // held. Call it via the handler.
1602 mHandler.obtainMessage(MSG_SET_NETWORK_TEMPLATE_ENABLED, enabled ? 1 : 0, 0, template)
1603 .sendToTarget();
1604 }
1605
1606 private void setNetworkTemplateEnabledInner(NetworkTemplate template, boolean enabled) {
Jeff Sharkey32566012014-12-02 18:30:14 -08001607 // TODO: reach into ConnectivityManager to proactively disable bringing
1608 // up this network, since we know that traffic will be blocked.
Jack Yu8781b682016-07-08 14:28:51 -07001609
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001610 if (template.getMatchRule() == MATCH_MOBILE) {
Jack Yu8781b682016-07-08 14:28:51 -07001611 // If mobile data usage hits the limit or if the user resumes the data, we need to
1612 // notify telephony.
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001613 final SubscriptionManager sm = mContext.getSystemService(SubscriptionManager.class);
1614 final TelephonyManager tm = mContext.getSystemService(TelephonyManager.class);
Jack Yu8781b682016-07-08 14:28:51 -07001615
Jeff Sharkey2e471452018-01-19 18:02:47 +09001616 final int[] subIds = ArrayUtils.defeatNullable(sm.getActiveSubscriptionIdList());
Jack Yu8781b682016-07-08 14:28:51 -07001617 for (int subId : subIds) {
1618 final String subscriberId = tm.getSubscriberId(subId);
1619 final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE,
Lorenzo Colittid3e4a1e2018-01-19 01:12:04 +09001620 TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true,
1621 true);
Jack Yu8781b682016-07-08 14:28:51 -07001622 // Template is matched when subscriber id matches.
1623 if (template.matches(probeIdent)) {
1624 tm.setPolicyDataEnabled(enabled, subId);
1625 }
1626 }
1627 }
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001628 }
1629
1630 /**
Jeff Sharkey64c96ec2017-08-30 16:28:26 -06001631 * Collect all ifaces from a {@link NetworkState} into the given set.
1632 */
1633 private static void collectIfaces(ArraySet<String> ifaces, NetworkState state) {
1634 final String baseIface = state.linkProperties.getInterfaceName();
1635 if (baseIface != null) {
1636 ifaces.add(baseIface);
1637 }
1638 for (LinkProperties stackedLink : state.linkProperties.getStackedLinks()) {
1639 final String stackedIface = stackedLink.getInterfaceName();
1640 if (stackedIface != null) {
1641 ifaces.add(stackedIface);
1642 }
1643 }
1644 }
1645
1646 /**
Jeff Sharkey21c9c452011-06-07 12:26:43 -07001647 * Examine all connected {@link NetworkState}, looking for
1648 * {@link NetworkPolicy} that need to be enforced. When matches found, set
1649 * remaining quota based on usage cycle and historical stats.
1650 */
Felipe Lemef0823852016-06-08 13:43:08 -07001651 void updateNetworkRulesNL() {
1652 if (LOGV) Slog.v(TAG, "updateNetworkRulesNL()");
Jeff Sharkey21c9c452011-06-07 12:26:43 -07001653
1654 final NetworkState[] states;
1655 try {
Jeff Sharkey2e471452018-01-19 18:02:47 +09001656 states = defeatNullable(mConnManager.getAllNetworkState());
Jeff Sharkey21c9c452011-06-07 12:26:43 -07001657 } catch (RemoteException e) {
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001658 // ignored; service lives in system_server
Jeff Sharkey21c9c452011-06-07 12:26:43 -07001659 return;
1660 }
1661
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001662 // First, generate identities of all connected networks so we can
1663 // quickly compare them against all defined policies below.
Jeff Sharkey9252b342018-01-19 07:58:35 +09001664 mNetIdToSubId.clear();
Jeff Sharkey64c96ec2017-08-30 16:28:26 -06001665 final ArrayMap<NetworkState, NetworkIdentity> identified = new ArrayMap<>();
Jeff Sharkey21c9c452011-06-07 12:26:43 -07001666 for (NetworkState state : states) {
Jeff Sharkey2e471452018-01-19 18:02:47 +09001667 if (state.network != null) {
1668 mNetIdToSubId.put(state.network.netId, parseSubId(state));
1669 }
Wei Liub8eaf452016-01-25 10:32:27 -08001670 if (state.networkInfo != null && state.networkInfo.isConnected()) {
Lorenzo Colittid3e4a1e2018-01-19 01:12:04 +09001671 final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state,
1672 true);
Jeff Sharkey64c96ec2017-08-30 16:28:26 -06001673 identified.put(state, ident);
Jeff Sharkey21c9c452011-06-07 12:26:43 -07001674 }
1675 }
1676
Jeff Sharkey64c96ec2017-08-30 16:28:26 -06001677 final ArraySet<String> newMeteredIfaces = new ArraySet<>();
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -07001678 long lowestRule = Long.MAX_VALUE;
Jeff Sharkeyfdfef572011-06-16 15:07:48 -07001679
Jeff Sharkey64c96ec2017-08-30 16:28:26 -06001680 // For every well-defined policy, compute remaining data based on
1681 // current cycle and historical stats, and push to kernel.
1682 final ArraySet<String> matchingIfaces = new ArraySet<>();
1683 for (int i = mNetworkPolicy.size() - 1; i >= 0; i--) {
1684 final NetworkPolicy policy = mNetworkPolicy.valueAt(i);
1685
1686 // Collect all ifaces that match this policy
1687 matchingIfaces.clear();
1688 for (int j = identified.size() - 1; j >= 0; j--) {
1689 if (policy.template.matches(identified.valueAt(j))) {
1690 collectIfaces(matchingIfaces, identified.keyAt(j));
1691 }
1692 }
Jeff Sharkey21c9c452011-06-07 12:26:43 -07001693
Jeff Sharkey21c9c452011-06-07 12:26:43 -07001694 if (LOGD) {
Jeff Sharkey64c96ec2017-08-30 16:28:26 -06001695 Slog.d(TAG, "Applying " + policy + " to ifaces " + matchingIfaces);
Jeff Sharkey21c9c452011-06-07 12:26:43 -07001696 }
1697
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -07001698 final boolean hasWarning = policy.warningBytes != LIMIT_DISABLED;
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001699 final boolean hasLimit = policy.limitBytes != LIMIT_DISABLED;
Jeff Sharkeyf60d0af2011-11-30 15:28:02 -08001700 if (hasLimit || policy.metered) {
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001701 final long quotaBytes;
Jeff Sharkey0f2910c2017-07-30 16:52:51 -06001702 if (hasLimit && policy.hasCycle()) {
1703 final Pair<ZonedDateTime, ZonedDateTime> cycle = NetworkPolicyManager
1704 .cycleIterator(policy).next();
1705 final long start = cycle.first.toInstant().toEpochMilli();
1706 final long end = cycle.second.toInstant().toEpochMilli();
1707 final long totalBytes = getTotalBytes(policy.template, start, end);
1708
1709 if (policy.lastLimitSnooze >= start) {
1710 // snoozing past quota, but we still need to restrict apps,
1711 // so push really high quota.
1712 quotaBytes = Long.MAX_VALUE;
1713 } else {
1714 // remaining "quota" bytes are based on total usage in
1715 // current cycle. kernel doesn't like 0-byte rules, so we
1716 // set 1-byte quota and disable the radio later.
1717 quotaBytes = Math.max(1, policy.limitBytes - totalBytes);
1718 }
1719 } else {
Jeff Sharkeyf60d0af2011-11-30 15:28:02 -08001720 // metered network, but no policy limit; we still need to
1721 // restrict apps, so push really high quota.
1722 quotaBytes = Long.MAX_VALUE;
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001723 }
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001724
Jeff Sharkey64c96ec2017-08-30 16:28:26 -06001725 if (matchingIfaces.size() > 1) {
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001726 // TODO: switch to shared quota once NMS supports
1727 Slog.w(TAG, "shared quota unsupported; generating rule for each iface");
Ashish Sharma50fd36d2011-06-15 19:34:53 -07001728 }
1729
Jeff Sharkey64c96ec2017-08-30 16:28:26 -06001730 for (int j = matchingIfaces.size() - 1; j >= 0; j--) {
1731 final String iface = matchingIfaces.valueAt(j);
1732 setInterfaceQuotaAsync(iface, quotaBytes);
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001733 newMeteredIfaces.add(iface);
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001734 }
1735 }
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -07001736
1737 // keep track of lowest warning or limit of active policies
1738 if (hasWarning && policy.warningBytes < lowestRule) {
1739 lowestRule = policy.warningBytes;
1740 }
1741 if (hasLimit && policy.limitBytes < lowestRule) {
1742 lowestRule = policy.limitBytes;
1743 }
1744 }
1745
Jeff Sharkey64c96ec2017-08-30 16:28:26 -06001746 // One final pass to catch any metered ifaces that don't have explicitly
1747 // defined policies; typically Wi-Fi networks.
1748 for (NetworkState state : states) {
1749 if (state.networkInfo != null && state.networkInfo.isConnected()
1750 && !state.networkCapabilities.hasCapability(NET_CAPABILITY_NOT_METERED)) {
1751 matchingIfaces.clear();
1752 collectIfaces(matchingIfaces, state);
1753 for (int j = matchingIfaces.size() - 1; j >= 0; j--) {
1754 final String iface = matchingIfaces.valueAt(j);
1755 if (!newMeteredIfaces.contains(iface)) {
1756 setInterfaceQuotaAsync(iface, Long.MAX_VALUE);
1757 newMeteredIfaces.add(iface);
1758 }
1759 }
1760 }
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -07001761 }
1762
Jeff Sharkey64c96ec2017-08-30 16:28:26 -06001763 // Remove quota from any interfaces that are no longer metered.
Dianne Hackborn497175b2014-07-01 12:56:08 -07001764 for (int i = mMeteredIfaces.size() - 1; i >= 0; i--) {
1765 final String iface = mMeteredIfaces.valueAt(i);
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001766 if (!newMeteredIfaces.contains(iface)) {
Jeff Sharkey64c96ec2017-08-30 16:28:26 -06001767 removeInterfaceQuotaAsync(iface);
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07001768 }
1769 }
1770 mMeteredIfaces = newMeteredIfaces;
1771
Jeff Sharkey36b414b2018-03-30 11:00:03 -06001772 final ContentResolver cr = mContext.getContentResolver();
1773 final boolean quotaEnabled = Settings.Global.getInt(cr,
1774 NETPOLICY_QUOTA_ENABLED, 1) != 0;
1775 final long quotaUnlimited = Settings.Global.getLong(cr,
1776 NETPOLICY_QUOTA_UNLIMITED, QUOTA_UNLIMITED_DEFAULT);
1777 final float quotaLimited = Settings.Global.getFloat(cr,
1778 NETPOLICY_QUOTA_LIMITED, QUOTA_LIMITED_DEFAULT);
1779
Jeff Sharkey9252b342018-01-19 07:58:35 +09001780 // Finally, calculate our opportunistic quotas
Jeff Sharkey9252b342018-01-19 07:58:35 +09001781 mSubscriptionOpportunisticQuota.clear();
1782 for (NetworkState state : states) {
Jeff Sharkey36b414b2018-03-30 11:00:03 -06001783 if (!quotaEnabled) continue;
Jeff Sharkey2e471452018-01-19 18:02:47 +09001784 if (state.network == null) continue;
Jeff Sharkey9252b342018-01-19 07:58:35 +09001785 final int subId = getSubIdLocked(state.network);
Jeff Sharkey2e471452018-01-19 18:02:47 +09001786 final SubscriptionPlan plan = getPrimarySubscriptionPlanLocked(subId);
Jeff Sharkey9252b342018-01-19 07:58:35 +09001787 if (plan == null) continue;
1788
Remi NGUYEN VAN5a89f942018-03-30 21:17:42 +09001789 final long quotaBytes;
Jeff Sharkey2e471452018-01-19 18:02:47 +09001790 final long limitBytes = plan.getDataLimitBytes();
Jeff Sharkey9252b342018-01-19 07:58:35 +09001791 if (limitBytes == SubscriptionPlan.BYTES_UNKNOWN) {
Remi NGUYEN VAN5a89f942018-03-30 21:17:42 +09001792 quotaBytes = OPPORTUNISTIC_QUOTA_UNKNOWN;
Jeff Sharkey2e471452018-01-19 18:02:47 +09001793 } else if (limitBytes == SubscriptionPlan.BYTES_UNLIMITED) {
Jeff Sharkey9252b342018-01-19 07:58:35 +09001794 // Unlimited data; let's use 20MiB/day (600MiB/month)
Jeff Sharkey36b414b2018-03-30 11:00:03 -06001795 quotaBytes = quotaUnlimited;
Jeff Sharkey9252b342018-01-19 07:58:35 +09001796 } else {
1797 // Limited data; let's only use 10% of remaining budget
Jeff Sharkey2e471452018-01-19 18:02:47 +09001798 final Pair<ZonedDateTime, ZonedDateTime> cycle = plan.cycleIterator().next();
Jeff Sharkey9252b342018-01-19 07:58:35 +09001799 final long start = cycle.first.toInstant().toEpochMilli();
1800 final long end = cycle.second.toInstant().toEpochMilli();
Remi NGUYEN VANbed7b972018-04-02 15:48:19 +09001801 final Instant now = mClock.instant();
1802 final long startOfDay = ZonedDateTime.ofInstant(now, cycle.first.getZone())
1803 .truncatedTo(ChronoUnit.DAYS)
1804 .toInstant().toEpochMilli();
Jeff Sharkey9252b342018-01-19 07:58:35 +09001805 final long totalBytes = getTotalBytes(
Remi NGUYEN VANbed7b972018-04-02 15:48:19 +09001806 NetworkTemplate.buildTemplateMobileAll(state.subscriberId),
1807 start, startOfDay);
Jeff Sharkey9252b342018-01-19 07:58:35 +09001808 final long remainingBytes = limitBytes - totalBytes;
Remi NGUYEN VANbed7b972018-04-02 15:48:19 +09001809 // Number of remaining days including current day
1810 final long remainingDays =
1811 1 + ((end - now.toEpochMilli() - 1) / TimeUnit.DAYS.toMillis(1));
Remi NGUYEN VAN5a89f942018-03-30 21:17:42 +09001812
Jeff Sharkey36b414b2018-03-30 11:00:03 -06001813 quotaBytes = Math.max(0, (long) ((remainingBytes / remainingDays) * quotaLimited));
Jeff Sharkey9252b342018-01-19 07:58:35 +09001814 }
1815
1816 mSubscriptionOpportunisticQuota.put(subId, quotaBytes);
1817 }
1818
Jeff Sharkeyfdfef572011-06-16 15:07:48 -07001819 final String[] meteredIfaces = mMeteredIfaces.toArray(new String[mMeteredIfaces.size()]);
Jeff Sharkey4414cea2011-06-24 17:05:24 -07001820 mHandler.obtainMessage(MSG_METERED_IFACES_CHANGED, meteredIfaces).sendToTarget();
Jeff Sharkey64c96ec2017-08-30 16:28:26 -06001821
1822 mHandler.obtainMessage(MSG_ADVISE_PERSIST_THRESHOLD, lowestRule).sendToTarget();
Jeff Sharkey22c055e2011-06-12 21:13:51 -07001823 }
1824
1825 /**
1826 * Once any {@link #mNetworkPolicy} are loaded from disk, ensure that we
1827 * have at least a default mobile policy defined.
1828 */
Hugo Benichi446c9c92017-04-10 09:41:10 +09001829 private void ensureActiveMobilePolicyAL() {
1830 if (LOGV) Slog.v(TAG, "ensureActiveMobilePolicyAL()");
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001831 if (mSuppressDefaultPolicy) return;
1832
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001833 final TelephonyManager tele = mContext.getSystemService(TelephonyManager.class);
1834 final SubscriptionManager sub = mContext.getSystemService(SubscriptionManager.class);
Jeff Sharkey8fc27e82012-04-04 20:40:58 -07001835
Jeff Sharkey2e471452018-01-19 18:02:47 +09001836 final int[] subIds = ArrayUtils.defeatNullable(sub.getActiveSubscriptionIdList());
Jeff Sharkey32566012014-12-02 18:30:14 -08001837 for (int subId : subIds) {
1838 final String subscriberId = tele.getSubscriberId(subId);
Hugo Benichi446c9c92017-04-10 09:41:10 +09001839 ensureActiveMobilePolicyAL(subId, subscriberId);
Jeff Sharkey32566012014-12-02 18:30:14 -08001840 }
1841 }
Jeff Sharkey8fc27e82012-04-04 20:40:58 -07001842
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07001843 /**
1844 * Once any {@link #mNetworkPolicy} are loaded from disk, ensure that we
1845 * have at least a default mobile policy defined.
1846 *
1847 * @param subId to build a default policy for
1848 * @param subscriberId that we check for an existing policy
1849 * @return true if a mobile network policy was added, or false one already existed.
1850 */
Hugo Benichi446c9c92017-04-10 09:41:10 +09001851 private boolean ensureActiveMobilePolicyAL(int subId, String subscriberId) {
Jeff Sharkey32566012014-12-02 18:30:14 -08001852 // Poke around to see if we already have a policy
1853 final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE,
Lorenzo Colittid3e4a1e2018-01-19 01:12:04 +09001854 TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true, true);
Jeff Sharkey32566012014-12-02 18:30:14 -08001855 for (int i = mNetworkPolicy.size() - 1; i >= 0; i--) {
1856 final NetworkTemplate template = mNetworkPolicy.keyAt(i);
1857 if (template.matches(probeIdent)) {
1858 if (LOGD) {
1859 Slog.d(TAG, "Found template " + template + " which matches subscriber "
1860 + NetworkIdentity.scrubSubscriberId(subscriberId));
1861 }
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07001862 return false;
Jeff Sharkey22c055e2011-06-12 21:13:51 -07001863 }
1864 }
1865
Jeff Sharkey32566012014-12-02 18:30:14 -08001866 Slog.i(TAG, "No policy for subscriber " + NetworkIdentity.scrubSubscriberId(subscriberId)
1867 + "; generating default policy");
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07001868 final NetworkPolicy policy = buildDefaultMobilePolicy(subId, subscriberId);
Hugo Benichi446c9c92017-04-10 09:41:10 +09001869 addNetworkPolicyAL(policy);
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07001870 return true;
1871 }
Jeff Sharkey22c055e2011-06-12 21:13:51 -07001872
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07001873 private long getPlatformDefaultWarningBytes() {
Fan Zhangda71ca02016-09-12 17:36:22 -07001874 final int dataWarningConfig = mContext.getResources().getInteger(
1875 com.android.internal.R.integer.config_networkPolicyDefaultWarning);
Fan Zhangda71ca02016-09-12 17:36:22 -07001876 if (dataWarningConfig == WARNING_DISABLED) {
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07001877 return WARNING_DISABLED;
Fan Zhangda71ca02016-09-12 17:36:22 -07001878 } else {
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07001879 return dataWarningConfig * MB_IN_BYTES;
Fan Zhangda71ca02016-09-12 17:36:22 -07001880 }
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07001881 }
Jeff Sharkey22c055e2011-06-12 21:13:51 -07001882
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07001883 private long getPlatformDefaultLimitBytes() {
1884 return LIMIT_DISABLED;
1885 }
1886
1887 @VisibleForTesting
1888 public NetworkPolicy buildDefaultMobilePolicy(int subId, String subscriberId) {
Jeff Sharkey32566012014-12-02 18:30:14 -08001889 final NetworkTemplate template = buildTemplateMobileAll(subscriberId);
Jeff Sharkey0f2910c2017-07-30 16:52:51 -06001890 final RecurrenceRule cycleRule = NetworkPolicy
1891 .buildRule(ZonedDateTime.now().getDayOfMonth(), ZoneId.systemDefault());
Jeff Sharkey17bebd22017-07-19 21:00:38 -06001892 final NetworkPolicy policy = new NetworkPolicy(template, cycleRule,
Jeff Sharkey0f2910c2017-07-30 16:52:51 -06001893 getPlatformDefaultWarningBytes(), getPlatformDefaultLimitBytes(),
1894 SNOOZE_NEVER, SNOOZE_NEVER, true, true);
1895 synchronized (mUidRulesFirstLock) {
1896 synchronized (mNetworkPoliciesSecondLock) {
1897 updateDefaultMobilePolicyAL(subId, policy);
1898 }
1899 }
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07001900 return policy;
Jeff Sharkey21c9c452011-06-07 12:26:43 -07001901 }
1902
Jeff Sharkey0f2910c2017-07-30 16:52:51 -06001903 /**
1904 * Update the given {@link NetworkPolicy} based on any carrier-provided
1905 * defaults via {@link SubscriptionPlan} or {@link CarrierConfigManager}.
1906 * Leaves policy untouched if the user has modified it.
1907 *
1908 * @return if the policy was modified
1909 */
1910 private boolean updateDefaultMobilePolicyAL(int subId, NetworkPolicy policy) {
1911 if (!policy.inferred) {
1912 if (LOGD) Slog.d(TAG, "Ignoring user-defined policy " + policy);
1913 return false;
1914 }
1915
1916 final NetworkPolicy original = new NetworkPolicy(policy.template, policy.cycleRule,
1917 policy.warningBytes, policy.limitBytes, policy.lastWarningSnooze,
1918 policy.lastLimitSnooze, policy.metered, policy.inferred);
1919
1920 final SubscriptionPlan[] plans = mSubscriptionPlans.get(subId);
1921 if (!ArrayUtils.isEmpty(plans)) {
1922 final SubscriptionPlan plan = plans[0];
1923 policy.cycleRule = plan.getCycleRule();
1924 final long planLimitBytes = plan.getDataLimitBytes();
1925 if (planLimitBytes == SubscriptionPlan.BYTES_UNKNOWN) {
1926 policy.warningBytes = getPlatformDefaultWarningBytes();
1927 policy.limitBytes = getPlatformDefaultLimitBytes();
1928 } else if (planLimitBytes == SubscriptionPlan.BYTES_UNLIMITED) {
1929 policy.warningBytes = NetworkPolicy.WARNING_DISABLED;
1930 policy.limitBytes = NetworkPolicy.LIMIT_DISABLED;
1931 } else {
1932 policy.warningBytes = (planLimitBytes * 9) / 10;
1933 switch (plan.getDataLimitBehavior()) {
1934 case SubscriptionPlan.LIMIT_BEHAVIOR_BILLED:
1935 case SubscriptionPlan.LIMIT_BEHAVIOR_DISABLED:
1936 policy.limitBytes = planLimitBytes;
1937 break;
1938 default:
1939 policy.limitBytes = NetworkPolicy.LIMIT_DISABLED;
1940 break;
1941 }
1942 }
1943 } else {
1944 final PersistableBundle config = mCarrierConfigManager.getConfigForSubId(subId);
1945 final int currentCycleDay;
1946 if (policy.cycleRule.isMonthly()) {
1947 currentCycleDay = policy.cycleRule.start.getDayOfMonth();
1948 } else {
1949 currentCycleDay = NetworkPolicy.CYCLE_NONE;
1950 }
1951 final int cycleDay = getCycleDayFromCarrierConfig(config, currentCycleDay);
1952 policy.cycleRule = NetworkPolicy.buildRule(cycleDay, ZoneId.systemDefault());
1953 policy.warningBytes = getWarningBytesFromCarrierConfig(config, policy.warningBytes);
1954 policy.limitBytes = getLimitBytesFromCarrierConfig(config, policy.limitBytes);
1955 }
1956
1957 if (policy.equals(original)) {
1958 return false;
1959 } else {
1960 Slog.d(TAG, "Updated " + original + " to " + policy);
1961 return true;
1962 }
1963 }
1964
Felipe Lemef0823852016-06-08 13:43:08 -07001965 private void readPolicyAL() {
1966 if (LOGV) Slog.v(TAG, "readPolicyAL()");
Jeff Sharkey21c9c452011-06-07 12:26:43 -07001967
1968 // clear any existing policy and read from disk
Jeff Sharkey22c055e2011-06-12 21:13:51 -07001969 mNetworkPolicy.clear();
Jeff Sharkey17bebd22017-07-19 21:00:38 -06001970 mSubscriptionPlans.clear();
Jeff Sharkeyb74799882017-07-28 16:55:41 -06001971 mSubscriptionPlansOwner.clear();
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07001972 mUidPolicy.clear();
Jeff Sharkey21c9c452011-06-07 12:26:43 -07001973
1974 FileInputStream fis = null;
1975 try {
1976 fis = mPolicyFile.openRead();
1977 final XmlPullParser in = Xml.newPullParser();
Wojciech Staszkiewicz9e9e2e72015-05-08 14:58:46 +01001978 in.setInput(fis, StandardCharsets.UTF_8.name());
Jeff Sharkey21c9c452011-06-07 12:26:43 -07001979
Felipe Leme46b451f2016-08-19 08:46:17 -07001980 // Must save the <restrict-background> tags and convert them to <uid-policy> later,
1981 // to skip UIDs that were explicitly blacklisted.
1982 final SparseBooleanArray whitelistedRestrictBackground = new SparseBooleanArray();
1983
Jeff Sharkey21c9c452011-06-07 12:26:43 -07001984 int type;
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001985 int version = VERSION_INIT;
Felipe Lemeb85a6372016-01-14 16:16:16 -08001986 boolean insideWhitelist = false;
Jeff Sharkey21c9c452011-06-07 12:26:43 -07001987 while ((type = in.next()) != END_DOCUMENT) {
1988 final String tag = in.getName();
1989 if (type == START_TAG) {
1990 if (TAG_POLICY_LIST.equals(tag)) {
Jeff Sharkey1b6519b2016-04-28 15:33:18 -06001991 final boolean oldValue = mRestrictBackground;
Jeff Sharkey21c9c452011-06-07 12:26:43 -07001992 version = readIntAttribute(in, ATTR_VERSION);
Sudheer Shanka543339f2017-07-28 15:18:07 -07001993 mLoadedRestrictBackground = (version >= VERSION_ADDED_RESTRICT_BACKGROUND)
1994 && readBooleanAttribute(in, ATTR_RESTRICT_BACKGROUND);
Jeff Sharkey21c9c452011-06-07 12:26:43 -07001995 } else if (TAG_NETWORK_POLICY.equals(tag)) {
1996 final int networkTemplate = readIntAttribute(in, ATTR_NETWORK_TEMPLATE);
1997 final String subscriberId = in.getAttributeValue(null, ATTR_SUBSCRIBER_ID);
Jeff Sharkey8fc27e82012-04-04 20:40:58 -07001998 final String networkId;
1999 if (version >= VERSION_ADDED_NETWORK_ID) {
2000 networkId = in.getAttributeValue(null, ATTR_NETWORK_ID);
2001 } else {
2002 networkId = null;
2003 }
Jeff Sharkey17bebd22017-07-19 21:00:38 -06002004 final RecurrenceRule cycleRule;
2005 if (version >= VERSION_ADDED_CYCLE) {
2006 final String start = readStringAttribute(in, ATTR_CYCLE_START);
2007 final String end = readStringAttribute(in, ATTR_CYCLE_END);
2008 final String period = readStringAttribute(in, ATTR_CYCLE_PERIOD);
2009 cycleRule = new RecurrenceRule(
2010 RecurrenceRule.convertZonedDateTime(start),
2011 RecurrenceRule.convertZonedDateTime(end),
2012 RecurrenceRule.convertPeriod(period));
Jeff Sharkey9bf31502012-03-09 17:07:21 -08002013 } else {
Jeff Sharkey17bebd22017-07-19 21:00:38 -06002014 final int cycleDay = readIntAttribute(in, ATTR_CYCLE_DAY);
2015 final String cycleTimezone;
2016 if (version >= VERSION_ADDED_TIMEZONE) {
2017 cycleTimezone = in.getAttributeValue(null, ATTR_CYCLE_TIMEZONE);
2018 } else {
2019 cycleTimezone = "UTC";
2020 }
2021 cycleRule = NetworkPolicy.buildRule(cycleDay, ZoneId.of(cycleTimezone));
Jeff Sharkey9bf31502012-03-09 17:07:21 -08002022 }
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002023 final long warningBytes = readLongAttribute(in, ATTR_WARNING_BYTES);
2024 final long limitBytes = readLongAttribute(in, ATTR_LIMIT_BYTES);
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -08002025 final long lastLimitSnooze;
2026 if (version >= VERSION_SPLIT_SNOOZE) {
2027 lastLimitSnooze = readLongAttribute(in, ATTR_LAST_LIMIT_SNOOZE);
2028 } else if (version >= VERSION_ADDED_SNOOZE) {
2029 lastLimitSnooze = readLongAttribute(in, ATTR_LAST_SNOOZE);
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07002030 } else {
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -08002031 lastLimitSnooze = SNOOZE_NEVER;
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07002032 }
Jeff Sharkeyf60d0af2011-11-30 15:28:02 -08002033 final boolean metered;
2034 if (version >= VERSION_ADDED_METERED) {
2035 metered = readBooleanAttribute(in, ATTR_METERED);
2036 } else {
2037 switch (networkTemplate) {
Jeff Sharkeye0c29952018-02-20 17:24:55 -07002038 case MATCH_MOBILE:
Jeff Sharkeyf60d0af2011-11-30 15:28:02 -08002039 metered = true;
2040 break;
2041 default:
2042 metered = false;
2043 }
2044 }
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -08002045 final long lastWarningSnooze;
2046 if (version >= VERSION_SPLIT_SNOOZE) {
2047 lastWarningSnooze = readLongAttribute(in, ATTR_LAST_WARNING_SNOOZE);
2048 } else {
2049 lastWarningSnooze = SNOOZE_NEVER;
2050 }
Jeff Sharkey837f9242012-03-20 16:52:20 -07002051 final boolean inferred;
2052 if (version >= VERSION_ADDED_INFERRED) {
2053 inferred = readBooleanAttribute(in, ATTR_INFERRED);
2054 } else {
2055 inferred = false;
2056 }
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002057
Jeff Sharkey32566012014-12-02 18:30:14 -08002058 final NetworkTemplate template = new NetworkTemplate(networkTemplate,
2059 subscriberId, networkId);
Jeff Sharkey7474fe7b2016-03-21 13:12:59 -06002060 if (template.isPersistable()) {
Jeff Sharkey17bebd22017-07-19 21:00:38 -06002061 mNetworkPolicy.put(template, new NetworkPolicy(template, cycleRule,
2062 warningBytes, limitBytes, lastWarningSnooze,
Jeff Sharkey7474fe7b2016-03-21 13:12:59 -06002063 lastLimitSnooze, metered, inferred));
2064 }
Jeff Sharkey17bebd22017-07-19 21:00:38 -06002065
2066 } else if (TAG_SUBSCRIPTION_PLAN.equals(tag)) {
2067 final String start = readStringAttribute(in, ATTR_CYCLE_START);
2068 final String end = readStringAttribute(in, ATTR_CYCLE_END);
2069 final String period = readStringAttribute(in, ATTR_CYCLE_PERIOD);
2070 final SubscriptionPlan.Builder builder = new SubscriptionPlan.Builder(
2071 RecurrenceRule.convertZonedDateTime(start),
2072 RecurrenceRule.convertZonedDateTime(end),
2073 RecurrenceRule.convertPeriod(period));
2074 builder.setTitle(readStringAttribute(in, ATTR_TITLE));
2075 builder.setSummary(readStringAttribute(in, ATTR_SUMMARY));
2076
2077 final long limitBytes = readLongAttribute(in, ATTR_LIMIT_BYTES,
2078 SubscriptionPlan.BYTES_UNKNOWN);
2079 final int limitBehavior = readIntAttribute(in, ATTR_LIMIT_BEHAVIOR,
2080 SubscriptionPlan.LIMIT_BEHAVIOR_UNKNOWN);
2081 if (limitBytes != SubscriptionPlan.BYTES_UNKNOWN
2082 && limitBehavior != SubscriptionPlan.LIMIT_BEHAVIOR_UNKNOWN) {
2083 builder.setDataLimit(limitBytes, limitBehavior);
2084 }
2085
2086 final long usageBytes = readLongAttribute(in, ATTR_USAGE_BYTES,
2087 SubscriptionPlan.BYTES_UNKNOWN);
2088 final long usageTime = readLongAttribute(in, ATTR_USAGE_TIME,
2089 SubscriptionPlan.TIME_UNKNOWN);
2090 if (usageBytes != SubscriptionPlan.BYTES_UNKNOWN
2091 && usageTime != SubscriptionPlan.TIME_UNKNOWN) {
2092 builder.setDataUsage(usageBytes, usageTime);
2093 }
2094
2095 final int subId = readIntAttribute(in, ATTR_SUB_ID);
2096 final SubscriptionPlan plan = builder.build();
2097 mSubscriptionPlans.put(subId, ArrayUtils.appendElement(
2098 SubscriptionPlan.class, mSubscriptionPlans.get(subId), plan));
2099
Jeff Sharkeyb74799882017-07-28 16:55:41 -06002100 final String ownerPackage = readStringAttribute(in, ATTR_OWNER_PACKAGE);
2101 mSubscriptionPlansOwner.put(subId, ownerPackage);
2102
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002103 } else if (TAG_UID_POLICY.equals(tag)) {
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002104 final int uid = readIntAttribute(in, ATTR_UID);
2105 final int policy = readIntAttribute(in, ATTR_POLICY);
2106
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002107 if (UserHandle.isApp(uid)) {
Felipe Lemef0823852016-06-08 13:43:08 -07002108 setUidPolicyUncheckedUL(uid, policy, false);
Jeff Sharkey497e4432011-06-14 17:27:29 -07002109 } else {
2110 Slog.w(TAG, "unable to apply policy to UID " + uid + "; ignoring");
2111 }
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002112 } else if (TAG_APP_POLICY.equals(tag)) {
Jeff Sharkey8a8b5812012-03-21 18:13:36 -07002113 final int appId = readIntAttribute(in, ATTR_APP_ID);
2114 final int policy = readIntAttribute(in, ATTR_POLICY);
2115
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002116 // TODO: set for other users during upgrade
Xiaohui Chenbe3b0672015-09-02 13:29:22 -07002117 // app policy is deprecated so this is only used in pre system user split.
2118 final int uid = UserHandle.getUid(UserHandle.USER_SYSTEM, appId);
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002119 if (UserHandle.isApp(uid)) {
Felipe Lemef0823852016-06-08 13:43:08 -07002120 setUidPolicyUncheckedUL(uid, policy, false);
Jeff Sharkey8a8b5812012-03-21 18:13:36 -07002121 } else {
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002122 Slog.w(TAG, "unable to apply policy to UID " + uid + "; ignoring");
Jeff Sharkey8a8b5812012-03-21 18:13:36 -07002123 }
Felipe Lemeb85a6372016-01-14 16:16:16 -08002124 } else if (TAG_WHITELIST.equals(tag)) {
2125 insideWhitelist = true;
2126 } else if (TAG_RESTRICT_BACKGROUND.equals(tag) && insideWhitelist) {
2127 final int uid = readIntAttribute(in, ATTR_UID);
Felipe Leme46b451f2016-08-19 08:46:17 -07002128 whitelistedRestrictBackground.append(uid, true);
Felipe Lemea9505cc2016-02-26 10:28:41 -08002129 } else if (TAG_REVOKED_RESTRICT_BACKGROUND.equals(tag) && insideWhitelist) {
2130 final int uid = readIntAttribute(in, ATTR_UID);
2131 mRestrictBackgroundWhitelistRevokedUids.put(uid, true);
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002132 }
Felipe Lemeb85a6372016-01-14 16:16:16 -08002133 } else if (type == END_TAG) {
2134 if (TAG_WHITELIST.equals(tag)) {
2135 insideWhitelist = false;
2136 }
2137
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002138 }
2139 }
2140
Felipe Leme46b451f2016-08-19 08:46:17 -07002141 final int size = whitelistedRestrictBackground.size();
2142 for (int i = 0; i < size; i++) {
2143 final int uid = whitelistedRestrictBackground.keyAt(i);
2144 final int policy = mUidPolicy.get(uid, POLICY_NONE);
2145 if ((policy & POLICY_REJECT_METERED_BACKGROUND) != 0) {
2146 Slog.w(TAG, "ignoring restrict-background-whitelist for " + uid
2147 + " because its policy is " + uidPoliciesToString(policy));
2148 continue;
2149 }
2150 if (UserHandle.isApp(uid)) {
2151 final int newPolicy = policy | POLICY_ALLOW_METERED_BACKGROUND;
2152 if (LOGV)
2153 Log.v(TAG, "new policy for " + uid + ": " + uidPoliciesToString(newPolicy));
2154 setUidPolicyUncheckedUL(uid, newPolicy, false);
2155 } else {
2156 Slog.w(TAG, "unable to update policy on UID " + uid);
2157 }
2158 }
2159
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002160 } catch (FileNotFoundException e) {
2161 // missing policy is okay, probably first boot
Narayan Kamath94bcdbc2017-07-17 15:32:53 +01002162 upgradeDefaultBackgroundDataUL();
Jeff Sharkey17bebd22017-07-19 21:00:38 -06002163 } catch (Exception e) {
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07002164 Log.wtf(TAG, "problem reading network policy", e);
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002165 } finally {
2166 IoUtils.closeQuietly(fis);
2167 }
2168 }
2169
Jeff Sharkey3a844fc2011-08-16 14:37:57 -07002170 /**
2171 * Upgrade legacy background data flags, notifying listeners of one last
2172 * change to always-true.
2173 */
Narayan Kamath94bcdbc2017-07-17 15:32:53 +01002174 private void upgradeDefaultBackgroundDataUL() {
2175 // This method is only called when we're unable to find the network policy flag, which
2176 // usually happens on first boot of a new device and not one that has received an OTA.
Jeff Sharkey3a844fc2011-08-16 14:37:57 -07002177
Narayan Kamath94bcdbc2017-07-17 15:32:53 +01002178 // Seed from the default value configured for this device.
Sudheer Shanka543339f2017-07-28 15:18:07 -07002179 mLoadedRestrictBackground = Settings.Global.getInt(
Narayan Kamath94bcdbc2017-07-17 15:32:53 +01002180 mContext.getContentResolver(), Global.DEFAULT_RESTRICT_BACKGROUND_DATA, 0) == 1;
2181
2182 // NOTE: We used to read the legacy setting here :
2183 //
2184 // final int legacyFlagValue = Settings.Secure.getInt(
2185 // mContext.getContentResolver(), Settings.Secure.BACKGROUND_DATA, ..);
2186 //
2187 // This is no longer necessary because we will never upgrade directly from Gingerbread
2188 // to O+. Devices upgrading from ICS onwards to O will have a netpolicy.xml file that
2189 // contains the correct value that we will continue to use.
Jeff Sharkey3a844fc2011-08-16 14:37:57 -07002190 }
2191
Jeff Sharkey43d2a172017-07-12 10:50:42 -06002192 /**
2193 * Perform upgrade step of moving any user-defined meterness overrides over
2194 * into {@link WifiConfiguration}.
2195 */
2196 private void upgradeWifiMeteredOverrideAL() {
2197 boolean modified = false;
2198 final WifiManager wm = mContext.getSystemService(WifiManager.class);
2199 final List<WifiConfiguration> configs = wm.getConfiguredNetworks();
2200 for (int i = 0; i < mNetworkPolicy.size(); ) {
2201 final NetworkPolicy policy = mNetworkPolicy.valueAt(i);
2202 if (policy.template.getMatchRule() == NetworkTemplate.MATCH_WIFI
2203 && !policy.inferred) {
2204 mNetworkPolicy.removeAt(i);
2205 modified = true;
2206
2207 final String networkId = resolveNetworkId(policy.template.getNetworkId());
2208 for (WifiConfiguration config : configs) {
2209 if (Objects.equals(resolveNetworkId(config), networkId)) {
2210 Slog.d(TAG, "Found network " + networkId + "; upgrading metered hint");
2211 config.meteredOverride = policy.metered
2212 ? WifiConfiguration.METERED_OVERRIDE_METERED
2213 : WifiConfiguration.METERED_OVERRIDE_NOT_METERED;
2214 wm.updateNetwork(config);
2215 }
2216 }
2217 } else {
2218 i++;
2219 }
2220 }
2221 if (modified) {
2222 writePolicyAL();
2223 }
2224 }
2225
Felipe Lemef0823852016-06-08 13:43:08 -07002226 void writePolicyAL() {
2227 if (LOGV) Slog.v(TAG, "writePolicyAL()");
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002228
2229 FileOutputStream fos = null;
2230 try {
2231 fos = mPolicyFile.startWrite();
2232
2233 XmlSerializer out = new FastXmlSerializer();
Wojciech Staszkiewicz9e9e2e72015-05-08 14:58:46 +01002234 out.setOutput(fos, StandardCharsets.UTF_8.name());
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002235 out.startDocument(null, true);
2236
2237 out.startTag(null, TAG_POLICY_LIST);
Jeff Sharkey8fc27e82012-04-04 20:40:58 -07002238 writeIntAttribute(out, ATTR_VERSION, VERSION_LATEST);
Jeff Sharkey46645002011-07-27 21:11:21 -07002239 writeBooleanAttribute(out, ATTR_RESTRICT_BACKGROUND, mRestrictBackground);
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002240
2241 // write all known network policies
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -07002242 for (int i = 0; i < mNetworkPolicy.size(); i++) {
2243 final NetworkPolicy policy = mNetworkPolicy.valueAt(i);
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -07002244 final NetworkTemplate template = policy.template;
Jeff Sharkey7474fe7b2016-03-21 13:12:59 -06002245 if (!template.isPersistable()) continue;
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -07002246
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002247 out.startTag(null, TAG_NETWORK_POLICY);
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -07002248 writeIntAttribute(out, ATTR_NETWORK_TEMPLATE, template.getMatchRule());
2249 final String subscriberId = template.getSubscriberId();
2250 if (subscriberId != null) {
2251 out.attribute(null, ATTR_SUBSCRIBER_ID, subscriberId);
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002252 }
Jeff Sharkey8fc27e82012-04-04 20:40:58 -07002253 final String networkId = template.getNetworkId();
2254 if (networkId != null) {
2255 out.attribute(null, ATTR_NETWORK_ID, networkId);
2256 }
Jeff Sharkey17bebd22017-07-19 21:00:38 -06002257 writeStringAttribute(out, ATTR_CYCLE_START,
2258 RecurrenceRule.convertZonedDateTime(policy.cycleRule.start));
2259 writeStringAttribute(out, ATTR_CYCLE_END,
2260 RecurrenceRule.convertZonedDateTime(policy.cycleRule.end));
2261 writeStringAttribute(out, ATTR_CYCLE_PERIOD,
2262 RecurrenceRule.convertPeriod(policy.cycleRule.period));
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002263 writeLongAttribute(out, ATTR_WARNING_BYTES, policy.warningBytes);
2264 writeLongAttribute(out, ATTR_LIMIT_BYTES, policy.limitBytes);
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -08002265 writeLongAttribute(out, ATTR_LAST_WARNING_SNOOZE, policy.lastWarningSnooze);
2266 writeLongAttribute(out, ATTR_LAST_LIMIT_SNOOZE, policy.lastLimitSnooze);
Jeff Sharkeyf60d0af2011-11-30 15:28:02 -08002267 writeBooleanAttribute(out, ATTR_METERED, policy.metered);
Jeff Sharkey837f9242012-03-20 16:52:20 -07002268 writeBooleanAttribute(out, ATTR_INFERRED, policy.inferred);
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002269 out.endTag(null, TAG_NETWORK_POLICY);
2270 }
2271
Jeff Sharkey17bebd22017-07-19 21:00:38 -06002272 // write all known subscription plans
2273 for (int i = 0; i < mSubscriptionPlans.size(); i++) {
2274 final int subId = mSubscriptionPlans.keyAt(i);
Jeff Sharkeyb74799882017-07-28 16:55:41 -06002275 final String ownerPackage = mSubscriptionPlansOwner.get(subId);
Jeff Sharkey17bebd22017-07-19 21:00:38 -06002276 final SubscriptionPlan[] plans = mSubscriptionPlans.valueAt(i);
2277 if (ArrayUtils.isEmpty(plans)) continue;
2278
2279 for (SubscriptionPlan plan : plans) {
2280 out.startTag(null, TAG_SUBSCRIPTION_PLAN);
2281 writeIntAttribute(out, ATTR_SUB_ID, subId);
Jeff Sharkeyb74799882017-07-28 16:55:41 -06002282 writeStringAttribute(out, ATTR_OWNER_PACKAGE, ownerPackage);
Jeff Sharkey17bebd22017-07-19 21:00:38 -06002283 final RecurrenceRule cycleRule = plan.getCycleRule();
2284 writeStringAttribute(out, ATTR_CYCLE_START,
2285 RecurrenceRule.convertZonedDateTime(cycleRule.start));
2286 writeStringAttribute(out, ATTR_CYCLE_END,
2287 RecurrenceRule.convertZonedDateTime(cycleRule.end));
2288 writeStringAttribute(out, ATTR_CYCLE_PERIOD,
2289 RecurrenceRule.convertPeriod(cycleRule.period));
2290 writeStringAttribute(out, ATTR_TITLE, plan.getTitle());
2291 writeStringAttribute(out, ATTR_SUMMARY, plan.getSummary());
2292 writeLongAttribute(out, ATTR_LIMIT_BYTES, plan.getDataLimitBytes());
2293 writeIntAttribute(out, ATTR_LIMIT_BEHAVIOR, plan.getDataLimitBehavior());
2294 writeLongAttribute(out, ATTR_USAGE_BYTES, plan.getDataUsageBytes());
2295 writeLongAttribute(out, ATTR_USAGE_TIME, plan.getDataUsageTime());
2296 out.endTag(null, TAG_SUBSCRIPTION_PLAN);
2297 }
2298 }
2299
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002300 // write all known uid policies
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002301 for (int i = 0; i < mUidPolicy.size(); i++) {
2302 final int uid = mUidPolicy.keyAt(i);
2303 final int policy = mUidPolicy.valueAt(i);
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002304
Jeff Sharkey497e4432011-06-14 17:27:29 -07002305 // skip writing empty policies
2306 if (policy == POLICY_NONE) continue;
2307
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002308 out.startTag(null, TAG_UID_POLICY);
2309 writeIntAttribute(out, ATTR_UID, uid);
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002310 writeIntAttribute(out, ATTR_POLICY, policy);
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002311 out.endTag(null, TAG_UID_POLICY);
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002312 }
2313
2314 out.endTag(null, TAG_POLICY_LIST);
Felipe Lemeb85a6372016-01-14 16:16:16 -08002315
2316 // write all whitelists
2317 out.startTag(null, TAG_WHITELIST);
2318
Felipe Lemea9505cc2016-02-26 10:28:41 -08002319 // revoked restrict background whitelist
Felipe Leme46b451f2016-08-19 08:46:17 -07002320 int size = mRestrictBackgroundWhitelistRevokedUids.size();
Felipe Lemea9505cc2016-02-26 10:28:41 -08002321 for (int i = 0; i < size; i++) {
2322 final int uid = mRestrictBackgroundWhitelistRevokedUids.keyAt(i);
2323 out.startTag(null, TAG_REVOKED_RESTRICT_BACKGROUND);
2324 writeIntAttribute(out, ATTR_UID, uid);
2325 out.endTag(null, TAG_REVOKED_RESTRICT_BACKGROUND);
2326 }
2327
Felipe Lemeb85a6372016-01-14 16:16:16 -08002328 out.endTag(null, TAG_WHITELIST);
2329
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002330 out.endDocument();
2331
2332 mPolicyFile.finishWrite(fos);
2333 } catch (IOException e) {
2334 if (fos != null) {
2335 mPolicyFile.failWrite(fos);
2336 }
2337 }
2338 }
2339
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07002340 @Override
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002341 public void setUidPolicy(int uid, int policy) {
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002342 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
Jeff Sharkeya4620792011-05-20 15:29:23 -07002343
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002344 if (!UserHandle.isApp(uid)) {
2345 throw new IllegalArgumentException("cannot apply policy to UID " + uid);
Jeff Sharkey497e4432011-06-14 17:27:29 -07002346 }
Felipe Lemef0823852016-06-08 13:43:08 -07002347 synchronized (mUidRulesFirstLock) {
Julia Reynolds72f83d62015-07-27 15:10:42 -04002348 final long token = Binder.clearCallingIdentity();
2349 try {
2350 final int oldPolicy = mUidPolicy.get(uid, POLICY_NONE);
2351 if (oldPolicy != policy) {
Felipe Lemef0823852016-06-08 13:43:08 -07002352 setUidPolicyUncheckedUL(uid, oldPolicy, policy, true);
Sudheer Shanka352dc572017-09-22 17:09:38 -07002353 mLogger.uidPolicyChanged(uid, oldPolicy, policy);
Julia Reynolds72f83d62015-07-27 15:10:42 -04002354 }
2355 } finally {
2356 Binder.restoreCallingIdentity(token);
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -07002357 }
2358 }
Jeff Sharkey497e4432011-06-14 17:27:29 -07002359 }
2360
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -07002361 @Override
2362 public void addUidPolicy(int uid, int policy) {
2363 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -07002364
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -07002365 if (!UserHandle.isApp(uid)) {
2366 throw new IllegalArgumentException("cannot apply policy to UID " + uid);
2367 }
2368
Felipe Lemef0823852016-06-08 13:43:08 -07002369 synchronized (mUidRulesFirstLock) {
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -07002370 final int oldPolicy = mUidPolicy.get(uid, POLICY_NONE);
2371 policy |= oldPolicy;
2372 if (oldPolicy != policy) {
Felipe Lemef0823852016-06-08 13:43:08 -07002373 setUidPolicyUncheckedUL(uid, oldPolicy, policy, true);
Sudheer Shanka352dc572017-09-22 17:09:38 -07002374 mLogger.uidPolicyChanged(uid, oldPolicy, policy);
Jeff Sharkey497e4432011-06-14 17:27:29 -07002375 }
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002376 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07002377 }
2378
2379 @Override
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -07002380 public void removeUidPolicy(int uid, int policy) {
2381 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
2382
2383 if (!UserHandle.isApp(uid)) {
2384 throw new IllegalArgumentException("cannot apply policy to UID " + uid);
2385 }
2386
Felipe Lemef0823852016-06-08 13:43:08 -07002387 synchronized (mUidRulesFirstLock) {
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -07002388 final int oldPolicy = mUidPolicy.get(uid, POLICY_NONE);
2389 policy = oldPolicy & ~policy;
2390 if (oldPolicy != policy) {
Felipe Lemef0823852016-06-08 13:43:08 -07002391 setUidPolicyUncheckedUL(uid, oldPolicy, policy, true);
Sudheer Shanka352dc572017-09-22 17:09:38 -07002392 mLogger.uidPolicyChanged(uid, oldPolicy, policy);
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -07002393 }
2394 }
2395 }
2396
Felipe Lemef0823852016-06-08 13:43:08 -07002397 private void setUidPolicyUncheckedUL(int uid, int oldPolicy, int policy, boolean persist) {
Sudheer Shanka5723ccb2018-02-13 11:08:19 -08002398 setUidPolicyUncheckedUL(uid, policy, false);
Felipe Leme923845f2016-03-02 13:42:48 -08002399
Felipe Leme57e3d312016-08-23 14:42:52 -07002400 final boolean notifyApp;
2401 if (!isUidValidForWhitelistRules(uid)) {
2402 notifyApp = false;
2403 } else {
Felipe Leme0ecfcd12016-09-06 12:49:48 -07002404 final boolean wasBlacklisted = oldPolicy == POLICY_REJECT_METERED_BACKGROUND;
2405 final boolean isBlacklisted = policy == POLICY_REJECT_METERED_BACKGROUND;
2406 final boolean wasWhitelisted = oldPolicy == POLICY_ALLOW_METERED_BACKGROUND;
2407 final boolean isWhitelisted = policy == POLICY_ALLOW_METERED_BACKGROUND;
Felipe Leme57e3d312016-08-23 14:42:52 -07002408 final boolean wasBlocked = wasBlacklisted || (mRestrictBackground && !wasWhitelisted);
2409 final boolean isBlocked = isBlacklisted || (mRestrictBackground && !isWhitelisted);
Felipe Leme03f90292016-09-08 18:10:32 -07002410 if ((wasWhitelisted && (!isWhitelisted || isBlacklisted))
2411 && mDefaultRestrictBackgroundWhitelistUids.get(uid)
2412 && !mRestrictBackgroundWhitelistRevokedUids.get(uid)) {
2413 if (LOGD)
2414 Slog.d(TAG, "Adding uid " + uid + " to revoked restrict background whitelist");
2415 mRestrictBackgroundWhitelistRevokedUids.append(uid, true);
2416 }
Felipe Leme57e3d312016-08-23 14:42:52 -07002417 notifyApp = wasBlocked != isBlocked;
2418 }
Felipe Leme0ecfcd12016-09-06 12:49:48 -07002419 mHandler.obtainMessage(MSG_POLICIES_CHANGED, uid, policy, Boolean.valueOf(notifyApp))
2420 .sendToTarget();
Sudheer Shanka5723ccb2018-02-13 11:08:19 -08002421 if (persist) {
2422 synchronized (mNetworkPoliciesSecondLock) {
2423 writePolicyAL();
2424 }
2425 }
Felipe Leme923845f2016-03-02 13:42:48 -08002426 }
2427
Felipe Lemef0823852016-06-08 13:43:08 -07002428 private void setUidPolicyUncheckedUL(int uid, int policy, boolean persist) {
Felipe Leme03f90292016-09-08 18:10:32 -07002429 if (policy == POLICY_NONE) {
2430 mUidPolicy.delete(uid);
2431 } else {
2432 mUidPolicy.put(uid, policy);
2433 }
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -07002434
2435 // uid policy changed, recompute rules and persist policy.
Sudheer Shankac9d94072017-02-22 22:13:55 +00002436 updateRulesForDataUsageRestrictionsUL(uid);
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -07002437 if (persist) {
Felipe Lemef0823852016-06-08 13:43:08 -07002438 synchronized (mNetworkPoliciesSecondLock) {
2439 writePolicyAL();
2440 }
Dianne Hackbornbe7c50e2014-06-30 14:43:28 -07002441 }
2442 }
2443
2444 @Override
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002445 public int getUidPolicy(int uid) {
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002446 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
2447
Felipe Lemef0823852016-06-08 13:43:08 -07002448 synchronized (mUidRulesFirstLock) {
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002449 return mUidPolicy.get(uid, POLICY_NONE);
Jeff Sharkeya4620792011-05-20 15:29:23 -07002450 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07002451 }
2452
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -07002453 @Override
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002454 public int[] getUidsWithPolicy(int policy) {
Jeff Sharkey854b2b12012-04-13 16:03:40 -07002455 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
2456
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002457 int[] uids = new int[0];
Felipe Lemef0823852016-06-08 13:43:08 -07002458 synchronized (mUidRulesFirstLock) {
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002459 for (int i = 0; i < mUidPolicy.size(); i++) {
2460 final int uid = mUidPolicy.keyAt(i);
2461 final int uidPolicy = mUidPolicy.valueAt(i);
Felipe Leme6f51a0a2016-08-24 15:11:51 -07002462 if ((policy == POLICY_NONE && uidPolicy == POLICY_NONE) ||
2463 (uidPolicy & policy) != 0) {
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002464 uids = appendInt(uids, uid);
Jeff Sharkey854b2b12012-04-13 16:03:40 -07002465 }
2466 }
2467 }
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002468 return uids;
2469 }
2470
2471 /**
Felipe Lemed17fda42016-04-29 11:12:45 -07002472 * Removes any persistable state associated with given {@link UserHandle}, persisting
2473 * if any changes that are made.
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002474 */
Felipe Lemef0823852016-06-08 13:43:08 -07002475 boolean removeUserStateUL(int userId, boolean writePolicy) {
Felipe Lemed17fda42016-04-29 11:12:45 -07002476
Sudheer Shanka352dc572017-09-22 17:09:38 -07002477 mLogger.removingUserState(userId);
Felipe Lemed17fda42016-04-29 11:12:45 -07002478 boolean changed = false;
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002479
Felipe Lemea110eec2016-04-29 09:58:06 -07002480 // Remove entries from revoked default restricted background UID whitelist
2481 for (int i = mRestrictBackgroundWhitelistRevokedUids.size() - 1; i >= 0; i--) {
2482 final int uid = mRestrictBackgroundWhitelistRevokedUids.keyAt(i);
2483 if (UserHandle.getUserId(uid) == userId) {
2484 mRestrictBackgroundWhitelistRevokedUids.removeAt(i);
Felipe Lemed17fda42016-04-29 11:12:45 -07002485 changed = true;
Felipe Lemea110eec2016-04-29 09:58:06 -07002486 }
2487 }
2488
Fyodor Kupolova31c5912016-01-22 11:26:09 -08002489 // Remove associated UID policies
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002490 int[] uids = new int[0];
2491 for (int i = 0; i < mUidPolicy.size(); i++) {
2492 final int uid = mUidPolicy.keyAt(i);
2493 if (UserHandle.getUserId(uid) == userId) {
2494 uids = appendInt(uids, uid);
2495 }
2496 }
2497
2498 if (uids.length > 0) {
2499 for (int uid : uids) {
2500 mUidPolicy.delete(uid);
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002501 }
Felipe Lemed17fda42016-04-29 11:12:45 -07002502 changed = true;
Fyodor Kupolova31c5912016-01-22 11:26:09 -08002503 }
Felipe Lemef0823852016-06-08 13:43:08 -07002504 synchronized (mNetworkPoliciesSecondLock) {
2505 updateRulesForGlobalChangeAL(true);
2506 if (writePolicy && changed) {
2507 writePolicyAL();
2508 }
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07002509 }
Felipe Lemed17fda42016-04-29 11:12:45 -07002510 return changed;
Jeff Sharkey854b2b12012-04-13 16:03:40 -07002511 }
2512
2513 @Override
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -07002514 public void registerListener(INetworkPolicyListener listener) {
Jeff Sharkey1a303952011-06-16 13:04:20 -07002515 // TODO: create permission for observing network policy
2516 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -07002517 mListeners.register(listener);
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -07002518 }
2519
2520 @Override
2521 public void unregisterListener(INetworkPolicyListener listener) {
Jeff Sharkey1a303952011-06-16 13:04:20 -07002522 // TODO: create permission for observing network policy
2523 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -07002524 mListeners.unregister(listener);
2525 }
2526
Jeff Sharkey1b861272011-05-22 00:34:52 -07002527 @Override
Jeff Sharkey22c055e2011-06-12 21:13:51 -07002528 public void setNetworkPolicies(NetworkPolicy[] policies) {
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002529 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
2530
Felipe Leme6a05eee2016-02-19 14:43:51 -08002531 final long token = Binder.clearCallingIdentity();
2532 try {
Felipe Lemef0823852016-06-08 13:43:08 -07002533 synchronized (mUidRulesFirstLock) {
2534 synchronized (mNetworkPoliciesSecondLock) {
2535 normalizePoliciesNL(policies);
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07002536 handleNetworkPoliciesUpdateAL(false);
Felipe Lemef0823852016-06-08 13:43:08 -07002537 }
Felipe Leme6a05eee2016-02-19 14:43:51 -08002538 }
2539 } finally {
2540 Binder.restoreCallingIdentity(token);
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002541 }
2542 }
2543
Hugo Benichi446c9c92017-04-10 09:41:10 +09002544 void addNetworkPolicyAL(NetworkPolicy policy) {
Svet Ganov16a16892015-04-16 10:32:04 -07002545 NetworkPolicy[] policies = getNetworkPolicies(mContext.getOpPackageName());
Jeff Sharkey32566012014-12-02 18:30:14 -08002546 policies = ArrayUtils.appendElement(NetworkPolicy.class, policies, policy);
2547 setNetworkPolicies(policies);
Jeff Sharkey9f6e4ba2012-04-19 23:01:08 -07002548 }
2549
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002550 @Override
Svet Ganov16a16892015-04-16 10:32:04 -07002551 public NetworkPolicy[] getNetworkPolicies(String callingPackage) {
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002552 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
Amit Mahajan7c5befa2015-07-14 10:26:00 -07002553 try {
Amit Mahajana9e72a72015-07-30 16:04:13 -07002554 mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE, TAG);
2555 // SKIP checking run-time OP_READ_PHONE_STATE since caller or self has PRIVILEGED
2556 // permission
Amit Mahajan7c5befa2015-07-14 10:26:00 -07002557 } catch (SecurityException e) {
2558 mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, TAG);
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002559
Amit Mahajan7c5befa2015-07-14 10:26:00 -07002560 if (mAppOps.noteOp(AppOpsManager.OP_READ_PHONE_STATE, Binder.getCallingUid(),
2561 callingPackage) != AppOpsManager.MODE_ALLOWED) {
2562 return new NetworkPolicy[0];
2563 }
Svet Ganov16a16892015-04-16 10:32:04 -07002564 }
2565
Felipe Lemef0823852016-06-08 13:43:08 -07002566 synchronized (mNetworkPoliciesSecondLock) {
Jeff Sharkey32566012014-12-02 18:30:14 -08002567 final int size = mNetworkPolicy.size();
2568 final NetworkPolicy[] policies = new NetworkPolicy[size];
2569 for (int i = 0; i < size; i++) {
2570 policies[i] = mNetworkPolicy.valueAt(i);
2571 }
2572 return policies;
2573 }
2574 }
2575
Felipe Lemef0823852016-06-08 13:43:08 -07002576 private void normalizePoliciesNL() {
2577 normalizePoliciesNL(getNetworkPolicies(mContext.getOpPackageName()));
Jeff Sharkey32566012014-12-02 18:30:14 -08002578 }
2579
Felipe Lemef0823852016-06-08 13:43:08 -07002580 private void normalizePoliciesNL(NetworkPolicy[] policies) {
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07002581 final TelephonyManager tele = mContext.getSystemService(TelephonyManager.class);
Jeff Sharkey32566012014-12-02 18:30:14 -08002582 final String[] merged = tele.getMergedSubscriberIds();
2583
2584 mNetworkPolicy.clear();
2585 for (NetworkPolicy policy : policies) {
2586 // When two normalized templates conflict, prefer the most
2587 // restrictive policy
2588 policy.template = NetworkTemplate.normalize(policy.template, merged);
2589 final NetworkPolicy existing = mNetworkPolicy.get(policy.template);
2590 if (existing == null || existing.compareTo(policy) > 0) {
2591 if (existing != null) {
2592 Slog.d(TAG, "Normalization replaced " + existing + " with " + policy);
2593 }
2594 mNetworkPolicy.put(policy.template, policy);
2595 }
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07002596 }
2597 }
2598
2599 @Override
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -08002600 public void snoozeLimit(NetworkTemplate template) {
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07002601 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
Jeff Sharkey6c0b4f32012-06-12 21:06:30 -07002602
2603 final long token = Binder.clearCallingIdentity();
2604 try {
2605 performSnooze(template, TYPE_LIMIT);
2606 } finally {
2607 Binder.restoreCallingIdentity(token);
2608 }
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -08002609 }
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07002610
Dianne Hackborn497175b2014-07-01 12:56:08 -07002611 void performSnooze(NetworkTemplate template, int type) {
Jeff Sharkey9911a282018-02-14 22:29:11 -07002612 final long currentTime = mClock.millis();
Felipe Lemef0823852016-06-08 13:43:08 -07002613 synchronized (mUidRulesFirstLock) {
2614 synchronized (mNetworkPoliciesSecondLock) {
2615 // find and snooze local policy that matches
2616 final NetworkPolicy policy = mNetworkPolicy.get(template);
2617 if (policy == null) {
2618 throw new IllegalArgumentException("unable to find policy for " + template);
2619 }
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07002620
Felipe Lemef0823852016-06-08 13:43:08 -07002621 switch (type) {
2622 case TYPE_WARNING:
2623 policy.lastWarningSnooze = currentTime;
2624 break;
2625 case TYPE_LIMIT:
2626 policy.lastLimitSnooze = currentTime;
2627 break;
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07002628 case TYPE_RAPID:
2629 policy.lastRapidSnooze = currentTime;
2630 break;
Felipe Lemef0823852016-06-08 13:43:08 -07002631 default:
2632 throw new IllegalArgumentException("unexpected type");
2633 }
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07002634
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07002635 handleNetworkPoliciesUpdateAL(true);
Felipe Lemef0823852016-06-08 13:43:08 -07002636 }
Jeff Sharkey21c9c452011-06-07 12:26:43 -07002637 }
2638 }
2639
2640 @Override
Felipe Leme70c8b9b2016-04-25 14:41:31 -07002641 public void onTetheringChanged(String iface, boolean tethering) {
2642 // No need to enforce permission because setRestrictBackground() will do it.
Felipe Lemef0823852016-06-08 13:43:08 -07002643 synchronized (mUidRulesFirstLock) {
Felipe Leme70c8b9b2016-04-25 14:41:31 -07002644 if (mRestrictBackground && tethering) {
2645 Log.d(TAG, "Tethering on (" + iface +"); disable Data Saver");
2646 setRestrictBackground(false);
2647 }
2648 }
2649 }
2650
2651 @Override
Jeff Sharkey46645002011-07-27 21:11:21 -07002652 public void setRestrictBackground(boolean restrictBackground) {
Felipe Leme29e72ea2016-09-08 13:26:55 -07002653 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "setRestrictBackground");
Felipe Leme6a05eee2016-02-19 14:43:51 -08002654 try {
Felipe Leme29e72ea2016-09-08 13:26:55 -07002655 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
2656 final long token = Binder.clearCallingIdentity();
2657 try {
Felipe Leme29e72ea2016-09-08 13:26:55 -07002658 synchronized (mUidRulesFirstLock) {
Felipe Leme29e72ea2016-09-08 13:26:55 -07002659 setRestrictBackgroundUL(restrictBackground);
Felipe Leme70c57c22016-03-29 10:45:13 -07002660 }
Felipe Leme29e72ea2016-09-08 13:26:55 -07002661 } finally {
2662 Binder.restoreCallingIdentity(token);
Felipe Leme6a05eee2016-02-19 14:43:51 -08002663 }
Felipe Leme6a05eee2016-02-19 14:43:51 -08002664 } finally {
Felipe Leme29e72ea2016-09-08 13:26:55 -07002665 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
Jeff Sharkey46645002011-07-27 21:11:21 -07002666 }
2667 }
2668
Felipe Lemef0823852016-06-08 13:43:08 -07002669 private void setRestrictBackgroundUL(boolean restrictBackground) {
Sudheer Shanka543339f2017-07-28 15:18:07 -07002670 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "setRestrictBackgroundUL");
Felipe Leme70c57c22016-03-29 10:45:13 -07002671 try {
Sudheer Shanka543339f2017-07-28 15:18:07 -07002672 if (restrictBackground == mRestrictBackground) {
2673 // Ideally, UI should never allow this scenario...
2674 Slog.w(TAG, "setRestrictBackgroundUL: already " + restrictBackground);
Felipe Leme70c57c22016-03-29 10:45:13 -07002675 return;
2676 }
Sudheer Shanka543339f2017-07-28 15:18:07 -07002677 Slog.d(TAG, "setRestrictBackgroundUL(): " + restrictBackground);
2678 final boolean oldRestrictBackground = mRestrictBackground;
2679 mRestrictBackground = restrictBackground;
2680 // Must whitelist foreground apps before turning data saver mode on.
2681 // TODO: there is no need to iterate through all apps here, just those in the foreground,
2682 // so it could call AM to get the UIDs of such apps, and iterate through them instead.
2683 updateRulesForRestrictBackgroundUL();
2684 try {
2685 if (!mNetworkManager.setDataSaverModeEnabled(mRestrictBackground)) {
2686 Slog.e(TAG,
2687 "Could not change Data Saver Mode on NMS to " + mRestrictBackground);
2688 mRestrictBackground = oldRestrictBackground;
2689 // TODO: if it knew the foreground apps (see TODO above), it could call
2690 // updateRulesForRestrictBackgroundUL() again to restore state.
2691 return;
2692 }
2693 } catch (RemoteException e) {
2694 // ignored; service lives in system_server
2695 }
jackqdyulei29c82ab2017-03-10 14:09:16 -08002696
Sudheer Shanka543339f2017-07-28 15:18:07 -07002697 sendRestrictBackgroundChangedMsg();
Sudheer Shanka352dc572017-09-22 17:09:38 -07002698 mLogger.restrictBackgroundChanged(oldRestrictBackground, mRestrictBackground);
Sudheer Shanka543339f2017-07-28 15:18:07 -07002699
2700 if (mRestrictBackgroundPowerState.globalBatterySaverEnabled) {
2701 mRestrictBackgroundChangedInBsm = true;
2702 }
2703 synchronized (mNetworkPoliciesSecondLock) {
2704 updateNotificationsNL();
2705 writePolicyAL();
2706 }
2707 } finally {
2708 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
jackqdyulei29c82ab2017-03-10 14:09:16 -08002709 }
Sudheer Shanka543339f2017-07-28 15:18:07 -07002710 }
2711
2712 private void sendRestrictBackgroundChangedMsg() {
2713 mHandler.removeMessages(MSG_RESTRICT_BACKGROUND_CHANGED);
2714 mHandler.obtainMessage(MSG_RESTRICT_BACKGROUND_CHANGED, mRestrictBackground ? 1 : 0, 0)
2715 .sendToTarget();
Felipe Leme70c57c22016-03-29 10:45:13 -07002716 }
2717
Felipe Lemeb85a6372016-01-14 16:16:16 -08002718 @Override
Felipe Leme1b103232016-01-22 09:44:57 -08002719 public int getRestrictBackgroundByCaller() {
2720 mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG);
2721 final int uid = Binder.getCallingUid();
Felipe Leme923845f2016-03-02 13:42:48 -08002722
Felipe Lemef0823852016-06-08 13:43:08 -07002723 synchronized (mUidRulesFirstLock) {
Felipe Leme923845f2016-03-02 13:42:48 -08002724 // Must clear identity because getUidPolicy() is restricted to system.
2725 final long token = Binder.clearCallingIdentity();
2726 final int policy;
2727 try {
2728 policy = getUidPolicy(uid);
2729 } finally {
2730 Binder.restoreCallingIdentity(token);
2731 }
2732 if (policy == POLICY_REJECT_METERED_BACKGROUND) {
2733 // App is blacklisted.
2734 return RESTRICT_BACKGROUND_STATUS_ENABLED;
2735 }
Felipe Leme1b103232016-01-22 09:44:57 -08002736 if (!mRestrictBackground) {
2737 return RESTRICT_BACKGROUND_STATUS_DISABLED;
2738 }
Felipe Leme46b451f2016-08-19 08:46:17 -07002739 return (mUidPolicy.get(uid) & POLICY_ALLOW_METERED_BACKGROUND) != 0
Felipe Leme1b103232016-01-22 09:44:57 -08002740 ? RESTRICT_BACKGROUND_STATUS_WHITELISTED
2741 : RESTRICT_BACKGROUND_STATUS_ENABLED;
2742 }
2743 }
2744
2745 @Override
Jeff Sharkey46645002011-07-27 21:11:21 -07002746 public boolean getRestrictBackground() {
2747 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
2748
Felipe Lemef0823852016-06-08 13:43:08 -07002749 synchronized (mUidRulesFirstLock) {
Jeff Sharkey46645002011-07-27 21:11:21 -07002750 return mRestrictBackground;
2751 }
2752 }
2753
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07002754 @Override
2755 public void setDeviceIdleMode(boolean enabled) {
2756 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
Felipe Leme873a83a2016-09-07 11:34:10 -07002757 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "setDeviceIdleMode");
2758 try {
2759 synchronized (mUidRulesFirstLock) {
Felipe Lemeea014392016-09-06 13:59:54 -07002760 if (mDeviceIdleMode == enabled) {
2761 return;
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07002762 }
Felipe Lemeea014392016-09-06 13:59:54 -07002763 mDeviceIdleMode = enabled;
Sudheer Shanka352dc572017-09-22 17:09:38 -07002764 mLogger.deviceIdleModeEnabled(enabled);
Felipe Lemeea014392016-09-06 13:59:54 -07002765 if (mSystemReady) {
2766 // Device idle change means we need to rebuild rules for all
2767 // known apps, so do a global refresh.
2768 updateRulesForRestrictPowerUL();
2769 }
2770 }
2771 if (enabled) {
2772 EventLogTags.writeDeviceIdleOnPhase("net");
2773 } else {
2774 EventLogTags.writeDeviceIdleOffPhase("net");
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07002775 }
Felipe Leme873a83a2016-09-07 11:34:10 -07002776 } finally {
2777 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07002778 }
2779 }
2780
Jeff Sharkeyf0ceede2011-08-02 17:22:34 -07002781 @Override
Jeff Sharkey43d2a172017-07-12 10:50:42 -06002782 public void setWifiMeteredOverride(String networkId, int meteredOverride) {
2783 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
Jeff Sharkeyf0ceede2011-08-02 17:22:34 -07002784 final long token = Binder.clearCallingIdentity();
2785 try {
Jeff Sharkey43d2a172017-07-12 10:50:42 -06002786 final WifiManager wm = mContext.getSystemService(WifiManager.class);
2787 final List<WifiConfiguration> configs = wm.getConfiguredNetworks();
2788 for (WifiConfiguration config : configs) {
2789 if (Objects.equals(resolveNetworkId(config), networkId)) {
2790 config.meteredOverride = meteredOverride;
2791 wm.updateNetwork(config);
2792 }
2793 }
Jeff Sharkeyf0ceede2011-08-02 17:22:34 -07002794 } finally {
2795 Binder.restoreCallingIdentity(token);
2796 }
2797 }
2798
Jeff Sharkey46645002011-07-27 21:11:21 -07002799 @Override
Jeff Sharkey43d2a172017-07-12 10:50:42 -06002800 @Deprecated
2801 public NetworkQuotaInfo getNetworkQuotaInfo(NetworkState state) {
2802 Log.w(TAG, "Shame on UID " + Binder.getCallingUid()
2803 + " for calling the hidden API getNetworkQuotaInfo(). Shame!");
2804 return new NetworkQuotaInfo();
Jeff Sharkey9f7cbf02012-04-12 18:34:54 -07002805 }
2806
Jeff Sharkey53313d72017-07-13 16:47:32 -06002807 private void enforceSubscriptionPlanAccess(int subId, int callingUid, String callingPackage) {
2808 // Verify they're not lying about package name
2809 mAppOps.checkPackage(callingUid, callingPackage);
2810
Jeff Sharkey53313d72017-07-13 16:47:32 -06002811 final SubscriptionInfo si;
Jeff Sharkey17bebd22017-07-19 21:00:38 -06002812 final PersistableBundle config;
Jeff Sharkey53313d72017-07-13 16:47:32 -06002813 final long token = Binder.clearCallingIdentity();
2814 try {
2815 si = mContext.getSystemService(SubscriptionManager.class)
2816 .getActiveSubscriptionInfo(subId);
Jeff Sharkey17bebd22017-07-19 21:00:38 -06002817 config = mCarrierConfigManager.getConfigForSubId(subId);
Jeff Sharkey53313d72017-07-13 16:47:32 -06002818 } finally {
2819 Binder.restoreCallingIdentity(token);
2820 }
2821
Jeff Sharkey17bebd22017-07-19 21:00:38 -06002822 // First check: is caller the CarrierService?
Jeff Sharkeyb74799882017-07-28 16:55:41 -06002823 if (si != null) {
2824 if (si.isEmbedded() && si.canManageSubscription(mContext, callingPackage)) {
2825 return;
2826 }
Jeff Sharkey53313d72017-07-13 16:47:32 -06002827 }
2828
Jeff Sharkey17bebd22017-07-19 21:00:38 -06002829 // Second check: has the CarrierService delegated access?
2830 if (config != null) {
2831 final String overridePackage = config
2832 .getString(CarrierConfigManager.KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING, null);
2833 if (!TextUtils.isEmpty(overridePackage)
2834 && Objects.equals(overridePackage, callingPackage)) {
2835 return;
2836 }
2837 }
Jeff Sharkey53313d72017-07-13 16:47:32 -06002838
Jeff Sharkey17bebd22017-07-19 21:00:38 -06002839 // Third check: is caller the fallback/default CarrierService?
2840 final String defaultPackage = mCarrierConfigManager.getDefaultCarrierServicePackageName();
2841 if (!TextUtils.isEmpty(defaultPackage)
2842 && Objects.equals(defaultPackage, callingPackage)) {
Jeff Sharkey53313d72017-07-13 16:47:32 -06002843 return;
2844 }
2845
Jeff Sharkey003d3e62018-03-30 14:35:04 -06002846 // Fourth check: is caller a testing app?
2847 final String testPackage = SystemProperties.get(PROP_SUB_PLAN_OWNER + "." + subId, null);
2848 if (!TextUtils.isEmpty(testPackage)
2849 && Objects.equals(testPackage, callingPackage)) {
2850 return;
2851 }
2852
2853 // Fifth check: is caller a legacy testing app?
2854 final String legacyTestPackage = SystemProperties.get("fw.sub_plan_owner." + subId, null);
2855 if (!TextUtils.isEmpty(legacyTestPackage)
2856 && Objects.equals(legacyTestPackage, callingPackage)) {
Jeff Sharkeya7f50462018-02-14 14:26:10 -07002857 return;
2858 }
2859
Jeff Sharkeyb74799882017-07-28 16:55:41 -06002860 // Final check: does the caller hold a permission?
2861 mContext.enforceCallingOrSelfPermission(MANAGE_SUBSCRIPTION_PLANS, TAG);
Jeff Sharkey53313d72017-07-13 16:47:32 -06002862 }
2863
2864 @Override
2865 public SubscriptionPlan[] getSubscriptionPlans(int subId, String callingPackage) {
2866 enforceSubscriptionPlanAccess(subId, Binder.getCallingUid(), callingPackage);
2867
Jeff Sharkey53313d72017-07-13 16:47:32 -06002868 final String fake = SystemProperties.get("fw.fake_plan");
2869 if (!TextUtils.isEmpty(fake)) {
2870 final List<SubscriptionPlan> plans = new ArrayList<>();
2871 if ("month_hard".equals(fake)) {
2872 plans.add(SubscriptionPlan.Builder
2873 .createRecurringMonthly(ZonedDateTime.parse("2007-03-14T00:00:00.000Z"))
2874 .setTitle("G-Mobile")
Jeff Sharkey53313d72017-07-13 16:47:32 -06002875 .setDataLimit(5 * TrafficStats.GB_IN_BYTES,
2876 SubscriptionPlan.LIMIT_BEHAVIOR_BILLED)
2877 .setDataUsage(1 * TrafficStats.GB_IN_BYTES,
2878 ZonedDateTime.now().minusHours(36).toInstant().toEpochMilli())
2879 .build());
Rajeev Kumar4701beb2017-07-26 17:03:45 -07002880 plans.add(SubscriptionPlan.Builder
2881 .createRecurringMonthly(ZonedDateTime.parse("2017-03-14T00:00:00.000Z"))
2882 .setTitle("G-Mobile Happy")
2883 .setDataLimit(SubscriptionPlan.BYTES_UNLIMITED,
2884 SubscriptionPlan.LIMIT_BEHAVIOR_BILLED)
2885 .setDataUsage(5 * TrafficStats.GB_IN_BYTES,
2886 ZonedDateTime.now().minusHours(36).toInstant().toEpochMilli())
2887 .build());
2888 plans.add(SubscriptionPlan.Builder
2889 .createRecurringMonthly(ZonedDateTime.parse("2017-03-14T00:00:00.000Z"))
2890 .setTitle("G-Mobile, Charged after limit")
2891 .setDataLimit(5 * TrafficStats.GB_IN_BYTES,
2892 SubscriptionPlan.LIMIT_BEHAVIOR_BILLED)
2893 .setDataUsage(5 * TrafficStats.GB_IN_BYTES,
2894 ZonedDateTime.now().minusHours(36).toInstant().toEpochMilli())
2895 .build());
Jeff Sharkey53313d72017-07-13 16:47:32 -06002896 } else if ("month_soft".equals(fake)) {
2897 plans.add(SubscriptionPlan.Builder
2898 .createRecurringMonthly(ZonedDateTime.parse("2007-03-14T00:00:00.000Z"))
2899 .setTitle("G-Mobile is the carriers name who this plan belongs to")
2900 .setSummary("Crazy unlimited bandwidth plan with incredibly long title "
2901 + "that should be cut off to prevent UI from looking terrible")
Jeff Sharkey53313d72017-07-13 16:47:32 -06002902 .setDataLimit(5 * TrafficStats.GB_IN_BYTES,
2903 SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED)
2904 .setDataUsage(1 * TrafficStats.GB_IN_BYTES,
2905 ZonedDateTime.now().minusHours(1).toInstant().toEpochMilli())
2906 .build());
Rajeev Kumar4701beb2017-07-26 17:03:45 -07002907 plans.add(SubscriptionPlan.Builder
2908 .createRecurringMonthly(ZonedDateTime.parse("2017-03-14T00:00:00.000Z"))
2909 .setTitle("G-Mobile, Throttled after limit")
2910 .setDataLimit(5 * TrafficStats.GB_IN_BYTES,
2911 SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED)
2912 .setDataUsage(5 * TrafficStats.GB_IN_BYTES,
2913 ZonedDateTime.now().minusHours(1).toInstant().toEpochMilli())
2914 .build());
2915 plans.add(SubscriptionPlan.Builder
2916 .createRecurringMonthly(ZonedDateTime.parse("2017-03-14T00:00:00.000Z"))
2917 .setTitle("G-Mobile, No data connection after limit")
2918 .setDataLimit(5 * TrafficStats.GB_IN_BYTES,
2919 SubscriptionPlan.LIMIT_BEHAVIOR_DISABLED)
2920 .setDataUsage(5 * TrafficStats.GB_IN_BYTES,
2921 ZonedDateTime.now().minusHours(1).toInstant().toEpochMilli())
2922 .build());
2923
Sundeep Ghuman09e0f572018-03-14 23:20:23 -07002924 } else if ("month_over".equals(fake)) {
2925 plans.add(SubscriptionPlan.Builder
2926 .createRecurringMonthly(ZonedDateTime.parse("2007-03-14T00:00:00.000Z"))
2927 .setTitle("G-Mobile is the carriers name who this plan belongs to")
2928 .setDataLimit(5 * TrafficStats.GB_IN_BYTES,
2929 SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED)
2930 .setDataUsage(6 * TrafficStats.GB_IN_BYTES,
2931 ZonedDateTime.now().minusHours(1).toInstant().toEpochMilli())
2932 .build());
2933 plans.add(SubscriptionPlan.Builder
2934 .createRecurringMonthly(ZonedDateTime.parse("2017-03-14T00:00:00.000Z"))
2935 .setTitle("G-Mobile, Throttled after limit")
2936 .setDataLimit(5 * TrafficStats.GB_IN_BYTES,
2937 SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED)
2938 .setDataUsage(5 * TrafficStats.GB_IN_BYTES,
2939 ZonedDateTime.now().minusHours(1).toInstant().toEpochMilli())
2940 .build());
2941 plans.add(SubscriptionPlan.Builder
2942 .createRecurringMonthly(ZonedDateTime.parse("2017-03-14T00:00:00.000Z"))
2943 .setTitle("G-Mobile, No data connection after limit")
2944 .setDataLimit(5 * TrafficStats.GB_IN_BYTES,
2945 SubscriptionPlan.LIMIT_BEHAVIOR_DISABLED)
2946 .setDataUsage(5 * TrafficStats.GB_IN_BYTES,
2947 ZonedDateTime.now().minusHours(1).toInstant().toEpochMilli())
2948 .build());
2949
Jeff Sharkey53313d72017-07-13 16:47:32 -06002950 } else if ("month_none".equals(fake)) {
2951 plans.add(SubscriptionPlan.Builder
2952 .createRecurringMonthly(ZonedDateTime.parse("2007-03-14T00:00:00.000Z"))
2953 .setTitle("G-Mobile")
2954 .build());
2955 } else if ("prepaid".equals(fake)) {
2956 plans.add(SubscriptionPlan.Builder
2957 .createNonrecurring(ZonedDateTime.now().minusDays(20),
2958 ZonedDateTime.now().plusDays(10))
2959 .setTitle("G-Mobile")
2960 .setDataLimit(512 * TrafficStats.MB_IN_BYTES,
2961 SubscriptionPlan.LIMIT_BEHAVIOR_DISABLED)
2962 .setDataUsage(100 * TrafficStats.MB_IN_BYTES,
2963 ZonedDateTime.now().minusHours(3).toInstant().toEpochMilli())
2964 .build());
2965 } else if ("prepaid_crazy".equals(fake)) {
2966 plans.add(SubscriptionPlan.Builder
2967 .createNonrecurring(ZonedDateTime.now().minusDays(20),
2968 ZonedDateTime.now().plusDays(10))
2969 .setTitle("G-Mobile Anytime")
2970 .setDataLimit(512 * TrafficStats.MB_IN_BYTES,
2971 SubscriptionPlan.LIMIT_BEHAVIOR_DISABLED)
2972 .setDataUsage(100 * TrafficStats.MB_IN_BYTES,
2973 ZonedDateTime.now().minusHours(3).toInstant().toEpochMilli())
2974 .build());
2975 plans.add(SubscriptionPlan.Builder
2976 .createNonrecurring(ZonedDateTime.now().minusDays(10),
2977 ZonedDateTime.now().plusDays(20))
2978 .setTitle("G-Mobile Nickel Nights")
2979 .setSummary("5¢/GB between 1-5AM")
Rajeev Kumar4701beb2017-07-26 17:03:45 -07002980 .setDataLimit(5 * TrafficStats.GB_IN_BYTES,
2981 SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED)
Jeff Sharkey53313d72017-07-13 16:47:32 -06002982 .setDataUsage(15 * TrafficStats.MB_IN_BYTES,
2983 ZonedDateTime.now().minusHours(30).toInstant().toEpochMilli())
2984 .build());
2985 plans.add(SubscriptionPlan.Builder
2986 .createNonrecurring(ZonedDateTime.now().minusDays(10),
2987 ZonedDateTime.now().plusDays(20))
2988 .setTitle("G-Mobile Bonus 3G")
2989 .setSummary("Unlimited 3G data")
Rajeev Kumar4701beb2017-07-26 17:03:45 -07002990 .setDataLimit(1 * TrafficStats.GB_IN_BYTES,
Jeff Sharkey53313d72017-07-13 16:47:32 -06002991 SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED)
2992 .setDataUsage(300 * TrafficStats.MB_IN_BYTES,
2993 ZonedDateTime.now().minusHours(1).toInstant().toEpochMilli())
2994 .build());
Rajeev Kumar4701beb2017-07-26 17:03:45 -07002995 } else if ("unlimited".equals(fake)) {
2996 plans.add(SubscriptionPlan.Builder
2997 .createNonrecurring(ZonedDateTime.now().minusDays(20),
2998 ZonedDateTime.now().plusDays(10))
2999 .setTitle("G-Mobile Awesome")
3000 .setDataLimit(SubscriptionPlan.BYTES_UNLIMITED,
3001 SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED)
3002 .setDataUsage(50 * TrafficStats.MB_IN_BYTES,
3003 ZonedDateTime.now().minusHours(3).toInstant().toEpochMilli())
3004 .build());
Jeff Sharkey53313d72017-07-13 16:47:32 -06003005 }
3006 return plans.toArray(new SubscriptionPlan[plans.size()]);
3007 }
3008
Jeff Sharkey4635f102017-09-01 11:27:13 -06003009 synchronized (mNetworkPoliciesSecondLock) {
3010 // Only give out plan details to the package that defined them,
3011 // so that we don't risk leaking plans between apps. We always
3012 // let in core system components (like the Settings app).
3013 final String ownerPackage = mSubscriptionPlansOwner.get(subId);
3014 if (Objects.equals(ownerPackage, callingPackage)
3015 || (UserHandle.getCallingAppId() == android.os.Process.SYSTEM_UID)) {
3016 return mSubscriptionPlans.get(subId);
3017 } else {
3018 Log.w(TAG, "Not returning plans because caller " + callingPackage
3019 + " doesn't match owner " + ownerPackage);
3020 return null;
Jeff Sharkey53313d72017-07-13 16:47:32 -06003021 }
Jeff Sharkey53313d72017-07-13 16:47:32 -06003022 }
3023 }
3024
3025 @Override
3026 public void setSubscriptionPlans(int subId, SubscriptionPlan[] plans, String callingPackage) {
3027 enforceSubscriptionPlanAccess(subId, Binder.getCallingUid(), callingPackage);
3028
Jeff Sharkey17bebd22017-07-19 21:00:38 -06003029 for (SubscriptionPlan plan : plans) {
3030 Preconditions.checkNotNull(plan);
Jeff Sharkey53313d72017-07-13 16:47:32 -06003031 }
3032
3033 final long token = Binder.clearCallingIdentity();
3034 try {
Jeff Sharkey17bebd22017-07-19 21:00:38 -06003035 synchronized (mUidRulesFirstLock) {
3036 synchronized (mNetworkPoliciesSecondLock) {
3037 mSubscriptionPlans.put(subId, plans);
Jeff Sharkeyb74799882017-07-28 16:55:41 -06003038 mSubscriptionPlansOwner.put(subId, callingPackage);
Jeff Sharkey0f2910c2017-07-30 16:52:51 -06003039
3040 final String subscriberId = mContext.getSystemService(TelephonyManager.class)
3041 .getSubscriberId(subId);
3042 ensureActiveMobilePolicyAL(subId, subscriberId);
3043 maybeUpdateMobilePolicyCycleAL(subId);
3044 handleNetworkPoliciesUpdateAL(true);
Jeff Sharkey17bebd22017-07-19 21:00:38 -06003045 }
Jeff Sharkey53313d72017-07-13 16:47:32 -06003046 }
Jeff Sharkeye92ed6f2018-01-10 20:47:42 -07003047
3048 final Intent intent = new Intent(SubscriptionManager.ACTION_SUBSCRIPTION_PLANS_CHANGED);
3049 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3050 intent.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, subId);
3051 mContext.sendBroadcast(intent, android.Manifest.permission.MANAGE_SUBSCRIPTION_PLANS);
Jeff Sharkey53313d72017-07-13 16:47:32 -06003052 } finally {
3053 Binder.restoreCallingIdentity(token);
3054 }
3055 }
3056
Jeff Sharkey003d3e62018-03-30 14:35:04 -06003057 /**
3058 * Only visible for testing purposes. This doesn't give any access to
3059 * existing plans; it simply lets the debug package define new plans.
3060 */
3061 void setSubscriptionPlansOwner(int subId, String packageName) {
3062 SystemProperties.set(PROP_SUB_PLAN_OWNER + "." + subId, packageName);
3063 }
3064
Jeff Sharkey53313d72017-07-13 16:47:32 -06003065 @Override
Jeff Sharkey717f52f2018-01-04 16:04:11 -07003066 public String getSubscriptionPlansOwner(int subId) {
3067 if (UserHandle.getCallingAppId() != android.os.Process.SYSTEM_UID) {
3068 throw new SecurityException();
3069 }
3070
3071 synchronized (mNetworkPoliciesSecondLock) {
3072 return mSubscriptionPlansOwner.get(subId);
3073 }
3074 }
3075
3076 @Override
Jeff Sharkey9252b342018-01-19 07:58:35 +09003077 public void setSubscriptionOverride(int subId, int overrideMask, int overrideValue,
3078 long timeoutMillis, String callingPackage) {
3079 enforceSubscriptionPlanAccess(subId, Binder.getCallingUid(), callingPackage);
3080
3081 // We can only override when carrier told us about plans
3082 synchronized (mNetworkPoliciesSecondLock) {
3083 if (ArrayUtils.isEmpty(mSubscriptionPlans.get(subId))) {
3084 throw new IllegalStateException(
3085 "Must provide SubscriptionPlan information before overriding");
3086 }
3087 }
3088
Jeff Sharkey36b414b2018-03-30 11:00:03 -06003089 // Only allow overrides when feature is enabled. However, we always
3090 // allow disabling of overrides for safety reasons.
3091 final boolean overrideEnabled = Settings.Global.getInt(mContext.getContentResolver(),
3092 NETPOLICY_OVERRIDE_ENABLED, 1) != 0;
3093 if (overrideEnabled || overrideValue == 0) {
3094 mHandler.sendMessage(mHandler.obtainMessage(MSG_SUBSCRIPTION_OVERRIDE,
3095 overrideMask, overrideValue, subId));
3096 if (timeoutMillis > 0) {
3097 mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_SUBSCRIPTION_OVERRIDE,
3098 overrideMask, 0, subId), timeoutMillis);
3099 }
Jeff Sharkey9252b342018-01-19 07:58:35 +09003100 }
3101 }
3102
3103 @Override
Jeff Sharkey8fc27e82012-04-04 20:40:58 -07003104 protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -06003105 if (!DumpUtils.checkDumpPermission(mContext, TAG, writer)) return;
Jeff Sharkey1b861272011-05-22 00:34:52 -07003106
Jeff Sharkey8fc27e82012-04-04 20:40:58 -07003107 final IndentingPrintWriter fout = new IndentingPrintWriter(writer, " ");
3108
Dianne Hackborn497175b2014-07-01 12:56:08 -07003109 final ArraySet<String> argSet = new ArraySet<String>(args.length);
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07003110 for (String arg : args) {
3111 argSet.add(arg);
3112 }
3113
Felipe Lemef0823852016-06-08 13:43:08 -07003114 synchronized (mUidRulesFirstLock) {
3115 synchronized (mNetworkPoliciesSecondLock) {
3116 if (argSet.contains("--unsnooze")) {
3117 for (int i = mNetworkPolicy.size()-1; i >= 0; i--) {
3118 mNetworkPolicy.valueAt(i).clearSnooze();
3119 }
3120
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07003121 handleNetworkPoliciesUpdateAL(true);
Felipe Lemef0823852016-06-08 13:43:08 -07003122
3123 fout.println("Cleared snooze timestamps");
3124 return;
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07003125 }
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -08003126
Felipe Lemef0823852016-06-08 13:43:08 -07003127 fout.print("System ready: "); fout.println(mSystemReady);
3128 fout.print("Restrict background: "); fout.println(mRestrictBackground);
3129 fout.print("Restrict power: "); fout.println(mRestrictPower);
3130 fout.print("Device idle: "); fout.println(mDeviceIdleMode);
Jeff Sharkey0f2910c2017-07-30 16:52:51 -06003131 fout.print("Metered ifaces: "); fout.println(String.valueOf(mMeteredIfaces));
3132
3133 fout.println();
Felipe Lemef0823852016-06-08 13:43:08 -07003134 fout.println("Network policies:");
Dianne Hackborn4a503b12015-08-06 22:19:06 -07003135 fout.increaseIndent();
Felipe Lemef0823852016-06-08 13:43:08 -07003136 for (int i = 0; i < mNetworkPolicy.size(); i++) {
3137 fout.println(mNetworkPolicy.valueAt(i).toString());
3138 }
3139 fout.decreaseIndent();
3140
Jeff Sharkey0f2910c2017-07-30 16:52:51 -06003141 fout.println();
3142 fout.println("Subscription plans:");
3143 fout.increaseIndent();
3144 for (int i = 0; i < mSubscriptionPlans.size(); i++) {
3145 final int subId = mSubscriptionPlans.keyAt(i);
3146 fout.println("Subscriber ID " + subId + ":");
3147 fout.increaseIndent();
3148 final SubscriptionPlan[] plans = mSubscriptionPlans.valueAt(i);
3149 if (!ArrayUtils.isEmpty(plans)) {
3150 for (SubscriptionPlan plan : plans) {
3151 fout.println(plan);
3152 }
3153 }
3154 fout.decreaseIndent();
3155 }
3156 fout.decreaseIndent();
Felipe Lemef0823852016-06-08 13:43:08 -07003157
Jeff Sharkey0f2910c2017-07-30 16:52:51 -06003158 fout.println();
Felipe Lemef0823852016-06-08 13:43:08 -07003159 fout.println("Policy for UIDs:");
3160 fout.increaseIndent();
3161 int size = mUidPolicy.size();
Dianne Hackborn4a503b12015-08-06 22:19:06 -07003162 for (int i = 0; i < size; i++) {
Felipe Lemef0823852016-06-08 13:43:08 -07003163 final int uid = mUidPolicy.keyAt(i);
3164 final int policy = mUidPolicy.valueAt(i);
Dianne Hackborn4a503b12015-08-06 22:19:06 -07003165 fout.print("UID=");
Felipe Lemef0823852016-06-08 13:43:08 -07003166 fout.print(uid);
3167 fout.print(" policy=");
Felipe Lemeb146f762016-08-19 09:52:16 -07003168 fout.print(uidPoliciesToString(policy));
Felipe Lemef0823852016-06-08 13:43:08 -07003169 fout.println();
3170 }
3171 fout.decreaseIndent();
3172
3173 size = mPowerSaveWhitelistExceptIdleAppIds.size();
3174 if (size > 0) {
3175 fout.println("Power save whitelist (except idle) app ids:");
3176 fout.increaseIndent();
3177 for (int i = 0; i < size; i++) {
3178 fout.print("UID=");
3179 fout.print(mPowerSaveWhitelistExceptIdleAppIds.keyAt(i));
3180 fout.print(": ");
3181 fout.print(mPowerSaveWhitelistExceptIdleAppIds.valueAt(i));
3182 fout.println();
3183 }
3184 fout.decreaseIndent();
3185 }
3186
3187 size = mPowerSaveWhitelistAppIds.size();
3188 if (size > 0) {
3189 fout.println("Power save whitelist app ids:");
3190 fout.increaseIndent();
3191 for (int i = 0; i < size; i++) {
3192 fout.print("UID=");
3193 fout.print(mPowerSaveWhitelistAppIds.keyAt(i));
3194 fout.print(": ");
3195 fout.print(mPowerSaveWhitelistAppIds.valueAt(i));
3196 fout.println();
3197 }
3198 fout.decreaseIndent();
3199 }
3200
Felipe Lemef0823852016-06-08 13:43:08 -07003201 size = mDefaultRestrictBackgroundWhitelistUids.size();
3202 if (size > 0) {
3203 fout.println("Default restrict background whitelist uids:");
3204 fout.increaseIndent();
3205 for (int i = 0; i < size; i++) {
3206 fout.print("UID=");
3207 fout.print(mDefaultRestrictBackgroundWhitelistUids.keyAt(i));
3208 fout.println();
3209 }
3210 fout.decreaseIndent();
3211 }
3212
3213 size = mRestrictBackgroundWhitelistRevokedUids.size();
3214 if (size > 0) {
3215 fout.println("Default restrict background whitelist uids revoked by users:");
3216 fout.increaseIndent();
3217 for (int i = 0; i < size; i++) {
3218 fout.print("UID=");
3219 fout.print(mRestrictBackgroundWhitelistRevokedUids.keyAt(i));
3220 fout.println();
3221 }
3222 fout.decreaseIndent();
3223 }
3224
3225 final SparseBooleanArray knownUids = new SparseBooleanArray();
3226 collectKeys(mUidState, knownUids);
3227 collectKeys(mUidRules, knownUids);
3228
3229 fout.println("Status for all known UIDs:");
3230 fout.increaseIndent();
3231 size = knownUids.size();
3232 for (int i = 0; i < size; i++) {
3233 final int uid = knownUids.keyAt(i);
3234 fout.print("UID=");
3235 fout.print(uid);
3236
3237 final int state = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
3238 fout.print(" state=");
3239 fout.print(state);
3240 if (state <= ActivityManager.PROCESS_STATE_TOP) {
3241 fout.print(" (fg)");
3242 } else {
Dianne Hackborn10fc4fd2017-12-19 17:23:13 -08003243 fout.print(state <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
Felipe Lemef0823852016-06-08 13:43:08 -07003244 ? " (fg svc)" : " (bg)");
3245 }
3246
3247 final int uidRules = mUidRules.get(uid, RULE_NONE);
3248 fout.print(" rules=");
3249 fout.print(uidRulesToString(uidRules));
3250 fout.println();
3251 }
3252 fout.decreaseIndent();
3253
3254 fout.println("Status for just UIDs with rules:");
3255 fout.increaseIndent();
3256 size = mUidRules.size();
3257 for (int i = 0; i < size; i++) {
3258 final int uid = mUidRules.keyAt(i);
3259 fout.print("UID=");
3260 fout.print(uid);
3261 final int uidRules = mUidRules.get(uid, RULE_NONE);
3262 fout.print(" rules=");
3263 fout.print(uidRulesToString(uidRules));
Dianne Hackborn4a503b12015-08-06 22:19:06 -07003264 fout.println();
3265 }
3266 fout.decreaseIndent();
Sudheer Shankae7361852017-03-07 11:51:46 -08003267
Sudheer Shanka04d61ae2018-01-17 12:16:57 -08003268 fout.println("Admin restricted uids for metered data:");
3269 fout.increaseIndent();
3270 size = mMeteredRestrictedUids.size();
3271 for (int i = 0; i < size; ++i) {
3272 fout.print("u" + mMeteredRestrictedUids.keyAt(i) + ": ");
3273 fout.println(mMeteredRestrictedUids.valueAt(i));
3274 }
3275 fout.decreaseIndent();
3276
Makoto Onuki49392d32018-04-11 13:51:02 -07003277 fout.println();
3278 mStatLogger.dump(fout);
3279
Sudheer Shanka352dc572017-09-22 17:09:38 -07003280 mLogger.dumpLogs(fout);
Dianne Hackborn4a503b12015-08-06 22:19:06 -07003281 }
Jeff Sharkey1b861272011-05-22 00:34:52 -07003282 }
3283 }
Jeff Sharkey9599cc52011-05-22 14:59:31 -07003284
3285 @Override
Felipe Leme50a235e2016-01-15 18:37:06 -08003286 public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
Dianne Hackborn354736e2016-08-22 17:00:05 -07003287 String[] args, ShellCallback callback, ResultReceiver resultReceiver) {
Felipe Lemeb1a65ee2016-02-08 10:12:01 -08003288 (new NetworkPolicyManagerShellCommand(mContext, this)).exec(
Dianne Hackborn354736e2016-08-22 17:00:05 -07003289 this, in, out, err, args, callback, resultReceiver);
Felipe Leme50a235e2016-01-15 18:37:06 -08003290 }
3291
Sudheer Shankad993dcf2018-02-11 12:22:16 -08003292 @VisibleForTesting
Jeff Sharkey9599cc52011-05-22 14:59:31 -07003293 public boolean isUidForeground(int uid) {
Felipe Lemef0823852016-06-08 13:43:08 -07003294 synchronized (mUidRulesFirstLock) {
Sudheer Shankad993dcf2018-02-11 12:22:16 -08003295 return isUidStateForeground(
3296 mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY));
Jeff Sharkey9599cc52011-05-22 14:59:31 -07003297 }
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -07003298 }
3299
Felipe Lemef0823852016-06-08 13:43:08 -07003300 private boolean isUidForegroundOnRestrictBackgroundUL(int uid) {
Felipe Lemeef89c902016-03-30 15:11:31 -07003301 final int procState = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
Sudheer Shankac9d94072017-02-22 22:13:55 +00003302 return isProcStateAllowedWhileOnRestrictBackground(procState);
Felipe Lemeef89c902016-03-30 15:11:31 -07003303 }
3304
Felipe Lemef0823852016-06-08 13:43:08 -07003305 private boolean isUidForegroundOnRestrictPowerUL(int uid) {
Felipe Leme781ba142016-05-09 16:24:48 -07003306 final int procState = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
3307 return isProcStateAllowedWhileIdleOrPowerSaveMode(procState);
3308 }
3309
Sudheer Shankad993dcf2018-02-11 12:22:16 -08003310 private boolean isUidStateForeground(int state) {
Dianne Hackborn497175b2014-07-01 12:56:08 -07003311 // only really in foreground when screen is also on
Sudheer Shankad993dcf2018-02-11 12:22:16 -08003312 return state <= NetworkPolicyManager.FOREGROUND_THRESHOLD_STATE;
Dianne Hackborn497175b2014-07-01 12:56:08 -07003313 }
3314
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07003315 /**
Dianne Hackbornd23e0d62015-05-15 16:36:12 -07003316 * Process state of UID changed; if needed, will trigger
Felipe Lemef0823852016-06-08 13:43:08 -07003317 * {@link #updateRulesForDataUsageRestrictionsUL(int)} and
3318 * {@link #updateRulesForPowerRestrictionsUL(int)}
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07003319 */
Sudheer Shankac9d94072017-02-22 22:13:55 +00003320 private void updateUidStateUL(int uid, int uidState) {
Felipe Leme873a83a2016-09-07 11:34:10 -07003321 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateUidStateUL");
3322 try {
3323 final int oldUidState = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
3324 if (oldUidState != uidState) {
3325 // state changed, push updated rules
3326 mUidState.put(uid, uidState);
Sudheer Shankac9d94072017-02-22 22:13:55 +00003327 updateRestrictBackgroundRulesOnUidStatusChangedUL(uid, oldUidState, uidState);
3328 if (isProcStateAllowedWhileIdleOrPowerSaveMode(oldUidState)
3329 != isProcStateAllowedWhileIdleOrPowerSaveMode(uidState) ) {
Sudheer Shanka9e77d232017-08-14 14:43:11 -07003330 updateRuleForAppIdleUL(uid);
Sudheer Shankac9d94072017-02-22 22:13:55 +00003331 if (mDeviceIdleMode) {
3332 updateRuleForDeviceIdleUL(uid);
Felipe Leme873a83a2016-09-07 11:34:10 -07003333 }
Sudheer Shankac9d94072017-02-22 22:13:55 +00003334 if (mRestrictPower) {
3335 updateRuleForRestrictPowerUL(uid);
Felipe Leme873a83a2016-09-07 11:34:10 -07003336 }
Sudheer Shankac9d94072017-02-22 22:13:55 +00003337 updateRulesForPowerRestrictionsUL(uid);
Felipe Leme781ba142016-05-09 16:24:48 -07003338 }
Sudheer Shankad993dcf2018-02-11 12:22:16 -08003339 updateNetworkStats(uid, isUidStateForeground(uidState));
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07003340 }
Felipe Leme873a83a2016-09-07 11:34:10 -07003341 } finally {
3342 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
Dianne Hackbornd23e0d62015-05-15 16:36:12 -07003343 }
3344 }
3345
Felipe Lemef0823852016-06-08 13:43:08 -07003346 private void removeUidStateUL(int uid) {
Dianne Hackbornd23e0d62015-05-15 16:36:12 -07003347 final int index = mUidState.indexOfKey(uid);
3348 if (index >= 0) {
3349 final int oldUidState = mUidState.valueAt(index);
3350 mUidState.removeAt(index);
3351 if (oldUidState != ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
Felipe Lemef0823852016-06-08 13:43:08 -07003352 updateRestrictBackgroundRulesOnUidStatusChangedUL(uid, oldUidState,
Sudheer Shankac9d94072017-02-22 22:13:55 +00003353 ActivityManager.PROCESS_STATE_CACHED_EMPTY);
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07003354 if (mDeviceIdleMode) {
Felipe Lemef0823852016-06-08 13:43:08 -07003355 updateRuleForDeviceIdleUL(uid);
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07003356 }
Felipe Leme011b98f2016-02-10 17:28:31 -08003357 if (mRestrictPower) {
Felipe Lemef0823852016-06-08 13:43:08 -07003358 updateRuleForRestrictPowerUL(uid);
Felipe Leme011b98f2016-02-10 17:28:31 -08003359 }
Sudheer Shankac9d94072017-02-22 22:13:55 +00003360 updateRulesForPowerRestrictionsUL(uid);
Felipe Lemef28983d2016-03-25 12:18:23 -07003361 updateNetworkStats(uid, false);
Dianne Hackborn497175b2014-07-01 12:56:08 -07003362 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07003363 }
3364 }
3365
Felipe Lemef28983d2016-03-25 12:18:23 -07003366 // adjust stats accounting based on foreground status
3367 private void updateNetworkStats(int uid, boolean uidForeground) {
Makoto Onuki0e6e3bd2017-03-20 14:53:00 -07003368 if (Trace.isTagEnabled(Trace.TRACE_TAG_NETWORK)) {
3369 Trace.traceBegin(Trace.TRACE_TAG_NETWORK,
3370 "updateNetworkStats: " + uid + "/" + (uidForeground ? "F" : "B"));
3371 }
Felipe Lemef28983d2016-03-25 12:18:23 -07003372 try {
3373 mNetworkStats.setUidForeground(uid, uidForeground);
Makoto Onuki0e6e3bd2017-03-20 14:53:00 -07003374 } finally {
3375 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
Felipe Lemef28983d2016-03-25 12:18:23 -07003376 }
3377 }
3378
Sudheer Shankac9d94072017-02-22 22:13:55 +00003379 private void updateRestrictBackgroundRulesOnUidStatusChangedUL(int uid, int oldUidState,
3380 int newUidState) {
Felipe Lemeef89c902016-03-30 15:11:31 -07003381 final boolean oldForeground =
Sudheer Shankac9d94072017-02-22 22:13:55 +00003382 isProcStateAllowedWhileOnRestrictBackground(oldUidState);
Felipe Lemeef89c902016-03-30 15:11:31 -07003383 final boolean newForeground =
Sudheer Shankac9d94072017-02-22 22:13:55 +00003384 isProcStateAllowedWhileOnRestrictBackground(newUidState);
Dianne Hackbornd23e0d62015-05-15 16:36:12 -07003385 if (oldForeground != newForeground) {
Sudheer Shankac9d94072017-02-22 22:13:55 +00003386 updateRulesForDataUsageRestrictionsUL(uid);
Dianne Hackbornd23e0d62015-05-15 16:36:12 -07003387 }
Sudheer Shankac9d94072017-02-22 22:13:55 +00003388 }
3389
Felipe Lemef0823852016-06-08 13:43:08 -07003390 void updateRulesForPowerSaveUL() {
Felipe Leme873a83a2016-09-07 11:34:10 -07003391 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForPowerSaveUL");
3392 try {
3393 updateRulesForWhitelistedPowerSaveUL(mRestrictPower, FIREWALL_CHAIN_POWERSAVE,
3394 mUidFirewallPowerSaveRules);
3395 } finally {
3396 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
3397 }
Felipe Leme011b98f2016-02-10 17:28:31 -08003398 }
3399
Felipe Lemef0823852016-06-08 13:43:08 -07003400 void updateRuleForRestrictPowerUL(int uid) {
3401 updateRulesForWhitelistedPowerSaveUL(uid, mRestrictPower, FIREWALL_CHAIN_POWERSAVE);
Felipe Leme011b98f2016-02-10 17:28:31 -08003402 }
3403
Felipe Lemef0823852016-06-08 13:43:08 -07003404 void updateRulesForDeviceIdleUL() {
Felipe Leme873a83a2016-09-07 11:34:10 -07003405 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForDeviceIdleUL");
3406 try {
3407 updateRulesForWhitelistedPowerSaveUL(mDeviceIdleMode, FIREWALL_CHAIN_DOZABLE,
3408 mUidFirewallDozableRules);
3409 } finally {
3410 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
3411 }
Felipe Leme011b98f2016-02-10 17:28:31 -08003412 }
3413
Felipe Lemef0823852016-06-08 13:43:08 -07003414 void updateRuleForDeviceIdleUL(int uid) {
3415 updateRulesForWhitelistedPowerSaveUL(uid, mDeviceIdleMode, FIREWALL_CHAIN_DOZABLE);
Felipe Leme011b98f2016-02-10 17:28:31 -08003416 }
3417
Felipe Lemef28983d2016-03-25 12:18:23 -07003418 // NOTE: since both fw_dozable and fw_powersave uses the same map
3419 // (mPowerSaveTempWhitelistAppIds) for whitelisting, we can reuse their logic in this method.
Felipe Lemef0823852016-06-08 13:43:08 -07003420 private void updateRulesForWhitelistedPowerSaveUL(boolean enabled, int chain,
Felipe Leme011b98f2016-02-10 17:28:31 -08003421 SparseIntArray rules) {
3422 if (enabled) {
3423 // Sync the whitelists before enabling the chain. We don't care about the rules if
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07003424 // we are disabling the chain.
Felipe Leme011b98f2016-02-10 17:28:31 -08003425 final SparseIntArray uidRules = rules;
Jeff Sharkeydc988062015-09-14 10:09:47 -07003426 uidRules.clear();
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07003427 final List<UserInfo> users = mUserManager.getUsers();
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07003428 for (int ui = users.size() - 1; ui >= 0; ui--) {
3429 UserInfo user = users.get(ui);
Sudheer Shanka54a92fd2017-04-26 10:43:23 -07003430 updateRulesForWhitelistedAppIds(uidRules, mPowerSaveTempWhitelistAppIds, user.id);
3431 updateRulesForWhitelistedAppIds(uidRules, mPowerSaveWhitelistAppIds, user.id);
3432 if (chain == FIREWALL_CHAIN_POWERSAVE) {
3433 updateRulesForWhitelistedAppIds(uidRules,
3434 mPowerSaveWhitelistExceptIdleAppIds, user.id);
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07003435 }
3436 }
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07003437 for (int i = mUidState.size() - 1; i >= 0; i--) {
Felipe Leme011b98f2016-02-10 17:28:31 -08003438 if (isProcStateAllowedWhileIdleOrPowerSaveMode(mUidState.valueAt(i))) {
Dianne Hackbornfd854ee2015-07-13 18:00:37 -07003439 uidRules.put(mUidState.keyAt(i), FIREWALL_RULE_ALLOW);
3440 }
3441 }
Sudheer Shankaaddebcc2017-10-03 09:43:20 -07003442 setUidFirewallRulesUL(chain, uidRules, CHAIN_TOGGLE_ENABLE);
Felipe Lemebc853dd2016-09-08 13:26:55 -07003443 } else {
Sudheer Shankaaddebcc2017-10-03 09:43:20 -07003444 setUidFirewallRulesUL(chain, null, CHAIN_TOGGLE_DISABLE);
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07003445 }
Xiaohui Chen8dca36d2015-06-19 12:44:59 -07003446 }
3447
Sudheer Shanka54a92fd2017-04-26 10:43:23 -07003448 private void updateRulesForWhitelistedAppIds(final SparseIntArray uidRules,
3449 final SparseBooleanArray whitelistedAppIds, int userId) {
3450 for (int i = whitelistedAppIds.size() - 1; i >= 0; --i) {
3451 if (whitelistedAppIds.valueAt(i)) {
3452 final int appId = whitelistedAppIds.keyAt(i);
3453 final int uid = UserHandle.getUid(userId, appId);
3454 uidRules.put(uid, FIREWALL_RULE_ALLOW);
3455 }
3456 }
3457 }
3458
3459 /**
3460 * @param deviceIdleMode if true then we don't consider
3461 * {@link #mPowerSaveWhitelistExceptIdleAppIds} for checking if the {@param uid} is
3462 * whitelisted.
3463 */
3464 private boolean isWhitelistedBatterySaverUL(int uid, boolean deviceIdleMode) {
Felipe Leme46c4fc32016-05-04 09:21:43 -07003465 final int appId = UserHandle.getAppId(uid);
Sudheer Shanka54a92fd2017-04-26 10:43:23 -07003466 boolean isWhitelisted = mPowerSaveTempWhitelistAppIds.get(appId)
3467 || mPowerSaveWhitelistAppIds.get(appId);
3468 if (!deviceIdleMode) {
3469 isWhitelisted = isWhitelisted || mPowerSaveWhitelistExceptIdleAppIds.get(appId);
3470 }
3471 return isWhitelisted;
Felipe Leme46c4fc32016-05-04 09:21:43 -07003472 }
3473
Felipe Lemef28983d2016-03-25 12:18:23 -07003474 // NOTE: since both fw_dozable and fw_powersave uses the same map
3475 // (mPowerSaveTempWhitelistAppIds) for whitelisting, we can reuse their logic in this method.
Felipe Lemef0823852016-06-08 13:43:08 -07003476 private void updateRulesForWhitelistedPowerSaveUL(int uid, boolean enabled, int chain) {
Felipe Leme011b98f2016-02-10 17:28:31 -08003477 if (enabled) {
Sudheer Shanka54a92fd2017-04-26 10:43:23 -07003478 final boolean isWhitelisted = isWhitelistedBatterySaverUL(uid,
3479 chain == FIREWALL_CHAIN_DOZABLE);
3480 if (isWhitelisted || isUidForegroundOnRestrictPowerUL(uid)) {
Felipe Leme011b98f2016-02-10 17:28:31 -08003481 setUidFirewallRule(chain, uid, FIREWALL_RULE_ALLOW);
Dianne Hackborn4a503b12015-08-06 22:19:06 -07003482 } else {
Felipe Leme011b98f2016-02-10 17:28:31 -08003483 setUidFirewallRule(chain, uid, FIREWALL_RULE_DEFAULT);
Dianne Hackborn4a503b12015-08-06 22:19:06 -07003484 }
3485 }
3486 }
3487
Felipe Lemef0823852016-06-08 13:43:08 -07003488 void updateRulesForAppIdleUL() {
Felipe Leme873a83a2016-09-07 11:34:10 -07003489 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForAppIdleUL");
3490 try {
3491 final SparseIntArray uidRules = mUidFirewallStandbyRules;
3492 uidRules.clear();
Jeff Sharkeydc988062015-09-14 10:09:47 -07003493
Felipe Leme873a83a2016-09-07 11:34:10 -07003494 // Fully update the app idle firewall chain.
3495 final List<UserInfo> users = mUserManager.getUsers();
3496 for (int ui = users.size() - 1; ui >= 0; ui--) {
3497 UserInfo user = users.get(ui);
3498 int[] idleUids = mUsageStats.getIdleUidsForUser(user.id);
3499 for (int uid : idleUids) {
3500 if (!mPowerSaveTempWhitelistAppIds.get(UserHandle.getAppId(uid), false)) {
3501 // quick check: if this uid doesn't have INTERNET permission, it
3502 // doesn't have network access anyway, so it is a waste to mess
3503 // with it here.
3504 if (hasInternetPermissions(uid)) {
3505 uidRules.put(uid, FIREWALL_RULE_DENY);
3506 }
Soi, Yoshinaria065da12015-12-22 12:02:18 +09003507 }
Dianne Hackborn4a503b12015-08-06 22:19:06 -07003508 }
3509 }
Jeff Sharkeydc988062015-09-14 10:09:47 -07003510
Sudheer Shankaaddebcc2017-10-03 09:43:20 -07003511 setUidFirewallRulesUL(FIREWALL_CHAIN_STANDBY, uidRules, CHAIN_TOGGLE_NONE);
Felipe Leme873a83a2016-09-07 11:34:10 -07003512 } finally {
3513 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
3514 }
Dianne Hackborn4a503b12015-08-06 22:19:06 -07003515 }
3516
Felipe Lemef0823852016-06-08 13:43:08 -07003517 void updateRuleForAppIdleUL(int uid) {
Felipe Leme70c57c22016-03-29 10:45:13 -07003518 if (!isUidValidForBlacklistRules(uid)) return;
Dianne Hackborn4a503b12015-08-06 22:19:06 -07003519
Makoto Onuki0e6e3bd2017-03-20 14:53:00 -07003520 if (Trace.isTagEnabled(Trace.TRACE_TAG_NETWORK)) {
3521 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRuleForAppIdleUL: " + uid );
3522 }
3523 try {
3524 int appId = UserHandle.getAppId(uid);
3525 if (!mPowerSaveTempWhitelistAppIds.get(appId) && isUidIdle(uid)
3526 && !isUidForegroundOnRestrictPowerUL(uid)) {
3527 setUidFirewallRule(FIREWALL_CHAIN_STANDBY, uid, FIREWALL_RULE_DENY);
3528 } else {
3529 setUidFirewallRule(FIREWALL_CHAIN_STANDBY, uid, FIREWALL_RULE_DEFAULT);
3530 }
3531 } finally {
3532 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
Dianne Hackborn4a503b12015-08-06 22:19:06 -07003533 }
3534 }
3535
Amith Yamasani0938f2f2016-09-16 12:46:31 -07003536 /**
3537 * Toggle the firewall standby chain and inform listeners if the uid rules have effectively
3538 * changed.
3539 */
Felipe Lemef0823852016-06-08 13:43:08 -07003540 void updateRulesForAppIdleParoleUL() {
Amith Yamasani0938f2f2016-09-16 12:46:31 -07003541 boolean paroled = mUsageStats.isAppIdleParoleOn();
3542 boolean enableChain = !paroled;
Felipe Lemef0823852016-06-08 13:43:08 -07003543 enableFirewallChainUL(FIREWALL_CHAIN_STANDBY, enableChain);
Amith Yamasani0938f2f2016-09-16 12:46:31 -07003544
3545 int ruleCount = mUidFirewallStandbyRules.size();
3546 for (int i = 0; i < ruleCount; i++) {
3547 int uid = mUidFirewallStandbyRules.keyAt(i);
3548 int oldRules = mUidRules.get(uid);
3549 if (enableChain) {
3550 // Chain wasn't enabled before and the other power-related
3551 // chains are whitelists, so we can clear the
3552 // MASK_ALL_NETWORKS part of the rules and re-inform listeners if
3553 // the effective rules result in blocking network access.
3554 oldRules &= MASK_METERED_NETWORKS;
3555 } else {
3556 // Skip if it had no restrictions to begin with
3557 if ((oldRules & MASK_ALL_NETWORKS) == 0) continue;
3558 }
Sudheer Shanka3af02942017-04-12 14:29:14 -07003559 final int newUidRules = updateRulesForPowerRestrictionsUL(uid, oldRules, paroled);
3560 if (newUidRules == RULE_NONE) {
3561 mUidRules.delete(uid);
3562 } else {
3563 mUidRules.put(uid, newUidRules);
3564 }
Amith Yamasani0938f2f2016-09-16 12:46:31 -07003565 }
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07003566 }
3567
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07003568 /**
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07003569 * Update rules that might be changed by {@link #mRestrictBackground},
3570 * {@link #mRestrictPower}, or {@link #mDeviceIdleMode} value.
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07003571 */
Felipe Lemef0823852016-06-08 13:43:08 -07003572 private void updateRulesForGlobalChangeAL(boolean restrictedNetworksChanged) {
Makoto Onuki0e6e3bd2017-03-20 14:53:00 -07003573 if (Trace.isTagEnabled(Trace.TRACE_TAG_NETWORK)) {
3574 Trace.traceBegin(Trace.TRACE_TAG_NETWORK,
3575 "updateRulesForGlobalChangeAL: " + (restrictedNetworksChanged ? "R" : "-"));
3576 }
Felipe Leme873a83a2016-09-07 11:34:10 -07003577 try {
Felipe Leme09700462016-09-08 09:33:48 -07003578 updateRulesForAppIdleUL();
Felipe Leme873a83a2016-09-07 11:34:10 -07003579 updateRulesForRestrictPowerUL();
3580 updateRulesForRestrictBackgroundUL();
Felipe Leme03e689d2016-03-02 16:17:38 -08003581
Felipe Leme873a83a2016-09-07 11:34:10 -07003582 // If the set of restricted networks may have changed, re-evaluate those.
3583 if (restrictedNetworksChanged) {
3584 normalizePoliciesNL();
3585 updateNetworkRulesNL();
3586 }
3587 } finally {
3588 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
Felipe Leme76010a32016-03-17 13:03:11 -07003589 }
3590 }
3591
Felipe Leme09700462016-09-08 09:33:48 -07003592 // TODO: rename / document to make it clear these are global (not app-specific) rules
Felipe Lemef0823852016-06-08 13:43:08 -07003593 private void updateRulesForRestrictPowerUL() {
Felipe Leme873a83a2016-09-07 11:34:10 -07003594 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForRestrictPowerUL");
3595 try {
3596 updateRulesForDeviceIdleUL();
Felipe Leme873a83a2016-09-07 11:34:10 -07003597 updateRulesForPowerSaveUL();
3598 updateRulesForAllAppsUL(TYPE_RESTRICT_POWER);
3599 } finally {
3600 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
3601 }
Felipe Lemef3e40642016-06-07 17:28:08 -07003602 }
3603
Felipe Lemef0823852016-06-08 13:43:08 -07003604 private void updateRulesForRestrictBackgroundUL() {
Felipe Leme873a83a2016-09-07 11:34:10 -07003605 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForRestrictBackgroundUL");
3606 try {
3607 updateRulesForAllAppsUL(TYPE_RESTRICT_BACKGROUND);
3608 } finally {
3609 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
3610 }
Felipe Lemef3e40642016-06-07 17:28:08 -07003611 }
3612
3613 private static final int TYPE_RESTRICT_BACKGROUND = 1;
3614 private static final int TYPE_RESTRICT_POWER = 2;
3615 @Retention(RetentionPolicy.SOURCE)
3616 @IntDef(flag = false, value = {
3617 TYPE_RESTRICT_BACKGROUND,
3618 TYPE_RESTRICT_POWER,
3619 })
3620 public @interface RestrictType {
3621 }
3622
3623 // TODO: refactor / consolidate all those updateXyz methods, there are way too many of them...
Felipe Lemef0823852016-06-08 13:43:08 -07003624 private void updateRulesForAllAppsUL(@RestrictType int type) {
Felipe Leme873a83a2016-09-07 11:34:10 -07003625 if (Trace.isTagEnabled(Trace.TRACE_TAG_NETWORK)) {
3626 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForRestrictPowerUL-" + type);
3627 }
3628 try {
Felipe Leme873a83a2016-09-07 11:34:10 -07003629 // update rules for all installed applications
Makoto Onuki0e6e3bd2017-03-20 14:53:00 -07003630
3631 final PackageManager pm = mContext.getPackageManager();
3632 final List<UserInfo> users;
3633 final List<ApplicationInfo> apps;
3634
3635 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "list-users");
3636 try {
3637 users = mUserManager.getUsers();
3638 } finally {
3639 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
3640 }
3641 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "list-uids");
3642 try {
3643 apps = pm.getInstalledApplications(
3644 PackageManager.MATCH_ANY_USER | PackageManager.MATCH_DISABLED_COMPONENTS
3645 | PackageManager.MATCH_DIRECT_BOOT_AWARE
3646 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
3647 } finally {
3648 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
3649 }
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07003650
Felipe Leme873a83a2016-09-07 11:34:10 -07003651 final int usersSize = users.size();
3652 final int appsSize = apps.size();
3653 for (int i = 0; i < usersSize; i++) {
3654 final UserInfo user = users.get(i);
3655 for (int j = 0; j < appsSize; j++) {
3656 final ApplicationInfo app = apps.get(j);
3657 final int uid = UserHandle.getUid(user.id, app.uid);
3658 switch (type) {
3659 case TYPE_RESTRICT_BACKGROUND:
Sudheer Shankac9d94072017-02-22 22:13:55 +00003660 updateRulesForDataUsageRestrictionsUL(uid);
Felipe Leme873a83a2016-09-07 11:34:10 -07003661 break;
3662 case TYPE_RESTRICT_POWER:
Sudheer Shankac9d94072017-02-22 22:13:55 +00003663 updateRulesForPowerRestrictionsUL(uid);
Felipe Leme873a83a2016-09-07 11:34:10 -07003664 break;
3665 default:
3666 Slog.w(TAG, "Invalid type for updateRulesForAllApps: " + type);
3667 }
Felipe Lemef3e40642016-06-07 17:28:08 -07003668 }
Jeff Sharkeyd0c6ccb2012-09-14 16:26:37 -07003669 }
Felipe Leme873a83a2016-09-07 11:34:10 -07003670 } finally {
Makoto Onuki0e6e3bd2017-03-20 14:53:00 -07003671 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07003672 }
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07003673 }
3674
Sudheer Shankaf34f3ec2017-08-03 11:02:56 -07003675 private void updateRulesForTempWhitelistChangeUL(int appId) {
Amith Yamasaniaf575b92015-05-29 15:35:26 -07003676 final List<UserInfo> users = mUserManager.getUsers();
Sudheer Shankaf34f3ec2017-08-03 11:02:56 -07003677 final int numUsers = users.size();
3678 for (int i = 0; i < numUsers; i++) {
Felipe Leme03e689d2016-03-02 16:17:38 -08003679 final UserInfo user = users.get(i);
Sudheer Shankaf34f3ec2017-08-03 11:02:56 -07003680 int uid = UserHandle.getUid(user.id, appId);
3681 // Update external firewall rules.
3682 updateRuleForAppIdleUL(uid);
3683 updateRuleForDeviceIdleUL(uid);
3684 updateRuleForRestrictPowerUL(uid);
3685 // Update internal rules.
3686 updateRulesForPowerRestrictionsUL(uid);
Amith Yamasaniaf575b92015-05-29 15:35:26 -07003687 }
3688 }
3689
Felipe Leme70c57c22016-03-29 10:45:13 -07003690 // TODO: the MEDIA / DRM restriction might not be needed anymore, in which case both
3691 // methods below could be merged into a isUidValidForRules() method.
3692 private boolean isUidValidForBlacklistRules(int uid) {
3693 // allow rules on specific system services, and any apps
Jeff Sharkey5294a2f2012-04-24 17:07:22 -07003694 if (uid == android.os.Process.MEDIA_UID || uid == android.os.Process.DRM_UID
Felipe Leme70c57c22016-03-29 10:45:13 -07003695 || (UserHandle.isApp(uid) && hasInternetPermissions(uid))) {
Jeff Sharkey5294a2f2012-04-24 17:07:22 -07003696 return true;
3697 }
3698
3699 return false;
3700 }
3701
Felipe Leme70c57c22016-03-29 10:45:13 -07003702 private boolean isUidValidForWhitelistRules(int uid) {
3703 return UserHandle.isApp(uid) && hasInternetPermissions(uid);
3704 }
3705
Amith Yamasani15e472352015-04-24 19:06:07 -07003706 private boolean isUidIdle(int uid) {
3707 final String[] packages = mContext.getPackageManager().getPackagesForUid(uid);
3708 final int userId = UserHandle.getUserId(uid);
3709
songjinshi0655edd2016-05-18 19:55:32 +08003710 if (packages != null) {
Jeff Sharkey377ded0f2016-01-10 13:15:41 -07003711 for (String packageName : packages) {
3712 if (!mUsageStats.isAppIdle(packageName, uid, userId)) {
3713 return false;
3714 }
Amith Yamasani15e472352015-04-24 19:06:07 -07003715 }
3716 }
3717 return true;
3718 }
3719
3720 /**
Felipe Leme47585ba2016-02-09 16:56:32 -08003721 * Checks if an uid has INTERNET permissions.
3722 * <p>
3723 * Useful for the cases where the lack of network access can simplify the rules.
Amith Yamasani15e472352015-04-24 19:06:07 -07003724 */
Felipe Leme47585ba2016-02-09 16:56:32 -08003725 private boolean hasInternetPermissions(int uid) {
Dianne Hackborn88e98df2015-03-23 13:29:14 -07003726 try {
Amith Yamasani2a4ac4e2016-02-12 12:43:15 -08003727 if (mIPm.checkUidPermission(Manifest.permission.INTERNET, uid)
Dianne Hackborn88e98df2015-03-23 13:29:14 -07003728 != PackageManager.PERMISSION_GRANTED) {
Felipe Leme47585ba2016-02-09 16:56:32 -08003729 return false;
Dianne Hackborn88e98df2015-03-23 13:29:14 -07003730 }
3731 } catch (RemoteException e) {
3732 }
Felipe Leme47585ba2016-02-09 16:56:32 -08003733 return true;
3734 }
3735
3736 /**
Felipe Leme03e95e22016-09-09 09:25:31 -07003737 * Clears all state - internal and external - associated with an UID.
3738 */
3739 private void onUidDeletedUL(int uid) {
3740 // First cleanup in-memory state synchronously...
3741 mUidRules.delete(uid);
3742 mUidPolicy.delete(uid);
3743 mUidFirewallStandbyRules.delete(uid);
3744 mUidFirewallDozableRules.delete(uid);
3745 mUidFirewallPowerSaveRules.delete(uid);
3746 mPowerSaveWhitelistExceptIdleAppIds.delete(uid);
3747 mPowerSaveWhitelistAppIds.delete(uid);
3748 mPowerSaveTempWhitelistAppIds.delete(uid);
3749
3750 // ...then update iptables asynchronously.
3751 mHandler.obtainMessage(MSG_RESET_FIREWALL_RULES_BY_UID, uid, 0).sendToTarget();
3752 }
3753
3754 /**
Felipe Lemef28983d2016-03-25 12:18:23 -07003755 * Applies network rules to bandwidth and firewall controllers based on uid policy.
Felipe Leme76010a32016-03-17 13:03:11 -07003756 *
Felipe Leme781ba142016-05-09 16:24:48 -07003757 * <p>There are currently 4 types of restriction rules:
Felipe Lemef28983d2016-03-25 12:18:23 -07003758 * <ul>
Felipe Leme781ba142016-05-09 16:24:48 -07003759 * <li>Doze mode
3760 * <li>App idle mode
Felipe Lemef28983d2016-03-25 12:18:23 -07003761 * <li>Battery Saver Mode (also referred as power save).
Felipe Leme46c4fc32016-05-04 09:21:43 -07003762 * <li>Data Saver Mode (The Feature Formerly Known As 'Restrict Background Data').
Felipe Lemef28983d2016-03-25 12:18:23 -07003763 * </ul>
Felipe Leme781ba142016-05-09 16:24:48 -07003764 *
3765 * <p>This method changes both the external firewall rules and the internal state.
Felipe Leme47585ba2016-02-09 16:56:32 -08003766 */
Felipe Leme03e95e22016-09-09 09:25:31 -07003767 private void updateRestrictionRulesForUidUL(int uid) {
Felipe Leme781ba142016-05-09 16:24:48 -07003768 // Methods below only changes the firewall rules for the power-related modes.
Felipe Lemef0823852016-06-08 13:43:08 -07003769 updateRuleForDeviceIdleUL(uid);
3770 updateRuleForAppIdleUL(uid);
3771 updateRuleForRestrictPowerUL(uid);
Felipe Leme781ba142016-05-09 16:24:48 -07003772
3773 // Update internal state for power-related modes.
Sudheer Shankac9d94072017-02-22 22:13:55 +00003774 updateRulesForPowerRestrictionsUL(uid);
Felipe Leme781ba142016-05-09 16:24:48 -07003775
3776 // Update firewall and internal rules for Data Saver Mode.
Sudheer Shankac9d94072017-02-22 22:13:55 +00003777 updateRulesForDataUsageRestrictionsUL(uid);
Felipe Lemef28983d2016-03-25 12:18:23 -07003778 }
3779
Felipe Leme70c57c22016-03-29 10:45:13 -07003780 /**
3781 * Applies network rules to bandwidth controllers based on process state and user-defined
3782 * restrictions (blacklist / whitelist).
3783 *
3784 * <p>
3785 * {@code netd} defines 3 firewall chains that govern whether an app has access to metered
3786 * networks:
3787 * <ul>
3788 * <li>@{code bw_penalty_box}: UIDs added to this chain do not have access (blacklist).
3789 * <li>@{code bw_happy_box}: UIDs added to this chain have access (whitelist), unless they're
3790 * also blacklisted.
3791 * <li>@{code bw_data_saver}: when enabled (through {@link #setRestrictBackground(boolean)}),
3792 * no UIDs other those whitelisted will have access.
3793 * <ul>
3794 *
3795 * <p>The @{code bw_penalty_box} and @{code bw_happy_box} are primarily managed through the
3796 * {@link #setUidPolicy(int, int)} and {@link #addRestrictBackgroundWhitelistedUid(int)} /
3797 * {@link #removeRestrictBackgroundWhitelistedUid(int)} methods (for blacklist and whitelist
3798 * respectively): these methods set the proper internal state (blacklist / whitelist), then call
Felipe Lemef0823852016-06-08 13:43:08 -07003799 * this ({@link #updateRulesForDataUsageRestrictionsUL(int)}) to propagate the rules to
Felipe Leme70c57c22016-03-29 10:45:13 -07003800 * {@link INetworkManagementService}, but this method should also be called in events (like
3801 * Data Saver Mode flips or UID state changes) that might affect the foreground app, since the
3802 * following rules should also be applied:
3803 *
3804 * <ul>
3805 * <li>When Data Saver mode is on, the foreground app should be temporarily added to
3806 * {@code bw_happy_box} before the @{code bw_data_saver} chain is enabled.
3807 * <li>If the foreground app is blacklisted by the user, it should be temporarily removed from
3808 * {@code bw_penalty_box}.
3809 * <li>When the app leaves foreground state, the temporary changes above should be reverted.
3810 * </ul>
3811 *
3812 * <p>For optimization, the rules are only applied on user apps that have internet access
3813 * permission, since there is no need to change the {@code iptables} rule if the app does not
3814 * have permission to use the internet.
3815 *
3816 * <p>The {@link #mUidRules} map is used to define the transtion of states of an UID.
Felipe Lemed31a97f2016-05-06 14:53:50 -07003817 *
Felipe Leme70c57c22016-03-29 10:45:13 -07003818 */
Sudheer Shankac9d94072017-02-22 22:13:55 +00003819 private void updateRulesForDataUsageRestrictionsUL(int uid) {
Makoto Onuki0e6e3bd2017-03-20 14:53:00 -07003820 if (Trace.isTagEnabled(Trace.TRACE_TAG_NETWORK)) {
3821 Trace.traceBegin(Trace.TRACE_TAG_NETWORK,
3822 "updateRulesForDataUsageRestrictionsUL: " + uid);
3823 }
3824 try {
3825 updateRulesForDataUsageRestrictionsULInner(uid);
3826 } finally {
3827 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
3828 }
3829 }
3830
3831 private void updateRulesForDataUsageRestrictionsULInner(int uid) {
Felipe Leme03e95e22016-09-09 09:25:31 -07003832 if (!isUidValidForWhitelistRules(uid)) {
Felipe Leme70c57c22016-03-29 10:45:13 -07003833 if (LOGD) Slog.d(TAG, "no need to update restrict data rules for uid " + uid);
Sudheer Shankac9d94072017-02-22 22:13:55 +00003834 return;
Felipe Leme70c57c22016-03-29 10:45:13 -07003835 }
Dianne Hackborn88e98df2015-03-23 13:29:14 -07003836
Dianne Hackborn497175b2014-07-01 12:56:08 -07003837 final int uidPolicy = mUidPolicy.get(uid, POLICY_NONE);
Felipe Leme46c4fc32016-05-04 09:21:43 -07003838 final int oldUidRules = mUidRules.get(uid, RULE_NONE);
Felipe Lemef0823852016-06-08 13:43:08 -07003839 final boolean isForeground = isUidForegroundOnRestrictBackgroundUL(uid);
Sudheer Shanka04d61ae2018-01-17 12:16:57 -08003840 final boolean isRestrictedByAdmin = isRestrictedByAdminUL(uid);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07003841
Felipe Leme781ba142016-05-09 16:24:48 -07003842 final boolean isBlacklisted = (uidPolicy & POLICY_REJECT_METERED_BACKGROUND) != 0;
Felipe Leme46b451f2016-08-19 08:46:17 -07003843 final boolean isWhitelisted = (uidPolicy & POLICY_ALLOW_METERED_BACKGROUND) != 0;
Felipe Leme781ba142016-05-09 16:24:48 -07003844 final int oldRule = oldUidRules & MASK_METERED_NETWORKS;
3845 int newRule = RULE_NONE;
Felipe Leme76010a32016-03-17 13:03:11 -07003846
Felipe Leme70c57c22016-03-29 10:45:13 -07003847 // First step: define the new rule based on user restrictions and foreground state.
Sudheer Shanka04d61ae2018-01-17 12:16:57 -08003848 if (isRestrictedByAdmin) {
3849 newRule = RULE_REJECT_METERED;
3850 } else if (isForeground) {
Felipe Leme781ba142016-05-09 16:24:48 -07003851 if (isBlacklisted || (mRestrictBackground && !isWhitelisted)) {
3852 newRule = RULE_TEMPORARY_ALLOW_METERED;
3853 } else if (isWhitelisted) {
3854 newRule = RULE_ALLOW_METERED;
Felipe Lemed31a97f2016-05-06 14:53:50 -07003855 }
3856 } else {
Felipe Leme781ba142016-05-09 16:24:48 -07003857 if (isBlacklisted) {
3858 newRule = RULE_REJECT_METERED;
3859 } else if (mRestrictBackground && isWhitelisted) {
3860 newRule = RULE_ALLOW_METERED;
Felipe Lemed31a97f2016-05-06 14:53:50 -07003861 }
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07003862 }
Felipe Leme781ba142016-05-09 16:24:48 -07003863 final int newUidRules = newRule | (oldUidRules & MASK_ALL_NETWORKS);
Felipe Leme46c4fc32016-05-04 09:21:43 -07003864
Felipe Lemef28983d2016-03-25 12:18:23 -07003865 if (LOGV) {
Felipe Lemef0823852016-06-08 13:43:08 -07003866 Log.v(TAG, "updateRuleForRestrictBackgroundUL(" + uid + ")"
Felipe Leme781ba142016-05-09 16:24:48 -07003867 + ": isForeground=" +isForeground
3868 + ", isBlacklisted=" + isBlacklisted
3869 + ", isWhitelisted=" + isWhitelisted
Sudheer Shanka04d61ae2018-01-17 12:16:57 -08003870 + ", isRestrictedByAdmin=" + isRestrictedByAdmin
Felipe Leme781ba142016-05-09 16:24:48 -07003871 + ", oldRule=" + uidRulesToString(oldRule)
3872 + ", newRule=" + uidRulesToString(newRule)
3873 + ", newUidRules=" + uidRulesToString(newUidRules)
3874 + ", oldUidRules=" + uidRulesToString(oldUidRules));
Felipe Lemef28983d2016-03-25 12:18:23 -07003875 }
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -07003876
Felipe Leme46c4fc32016-05-04 09:21:43 -07003877 if (newUidRules == RULE_NONE) {
Jeff Sharkey350083e2011-06-29 10:45:16 -07003878 mUidRules.delete(uid);
3879 } else {
Felipe Leme46c4fc32016-05-04 09:21:43 -07003880 mUidRules.put(uid, newUidRules);
Jeff Sharkey350083e2011-06-29 10:45:16 -07003881 }
Jeff Sharkeyc006f1a2011-05-19 17:12:49 -07003882
Felipe Leme70c57c22016-03-29 10:45:13 -07003883 // Second step: apply bw changes based on change of state.
Felipe Leme781ba142016-05-09 16:24:48 -07003884 if (newRule != oldRule) {
Hugo Benichi2966c182017-03-28 17:17:13 +09003885 if (hasRule(newRule, RULE_TEMPORARY_ALLOW_METERED)) {
Felipe Leme70c57c22016-03-29 10:45:13 -07003886 // Temporarily whitelist foreground app, removing from blacklist if necessary
3887 // (since bw_penalty_box prevails over bw_happy_box).
3888
3889 setMeteredNetworkWhitelist(uid, true);
3890 // TODO: if statement below is used to avoid an unnecessary call to netd / iptables,
3891 // but ideally it should be just:
3892 // setMeteredNetworkBlacklist(uid, isBlacklisted);
Felipe Leme781ba142016-05-09 16:24:48 -07003893 if (isBlacklisted) {
Felipe Leme70c57c22016-03-29 10:45:13 -07003894 setMeteredNetworkBlacklist(uid, false);
3895 }
Hugo Benichi2966c182017-03-28 17:17:13 +09003896 } else if (hasRule(oldRule, RULE_TEMPORARY_ALLOW_METERED)) {
Felipe Leme70c57c22016-03-29 10:45:13 -07003897 // Remove temporary whitelist from app that is not on foreground anymore.
3898
3899 // TODO: if statements below are used to avoid unnecessary calls to netd / iptables,
3900 // but ideally they should be just:
3901 // setMeteredNetworkWhitelist(uid, isWhitelisted);
3902 // setMeteredNetworkBlacklist(uid, isBlacklisted);
Felipe Leme781ba142016-05-09 16:24:48 -07003903 if (!isWhitelisted) {
Felipe Leme70c57c22016-03-29 10:45:13 -07003904 setMeteredNetworkWhitelist(uid, false);
3905 }
Sudheer Shanka04d61ae2018-01-17 12:16:57 -08003906 if (isBlacklisted || isRestrictedByAdmin) {
Felipe Leme70c57c22016-03-29 10:45:13 -07003907 setMeteredNetworkBlacklist(uid, true);
3908 }
Hugo Benichi2966c182017-03-28 17:17:13 +09003909 } else if (hasRule(newRule, RULE_REJECT_METERED)
3910 || hasRule(oldRule, RULE_REJECT_METERED)) {
Felipe Leme70c57c22016-03-29 10:45:13 -07003911 // Flip state because app was explicitly added or removed to blacklist.
Sudheer Shanka04d61ae2018-01-17 12:16:57 -08003912 setMeteredNetworkBlacklist(uid, (isBlacklisted || isRestrictedByAdmin));
Hugo Benichi2966c182017-03-28 17:17:13 +09003913 if (hasRule(oldRule, RULE_REJECT_METERED) && isWhitelisted) {
Felipe Leme70c57c22016-03-29 10:45:13 -07003914 // Since blacklist prevails over whitelist, we need to handle the special case
3915 // where app is whitelisted and blacklisted at the same time (although such
3916 // scenario should be blocked by the UI), then blacklist is removed.
Felipe Leme781ba142016-05-09 16:24:48 -07003917 setMeteredNetworkWhitelist(uid, isWhitelisted);
Felipe Leme70c57c22016-03-29 10:45:13 -07003918 }
Hugo Benichi2966c182017-03-28 17:17:13 +09003919 } else if (hasRule(newRule, RULE_ALLOW_METERED)
3920 || hasRule(oldRule, RULE_ALLOW_METERED)) {
Felipe Leme70c57c22016-03-29 10:45:13 -07003921 // Flip state because app was explicitly added or removed to whitelist.
Felipe Leme781ba142016-05-09 16:24:48 -07003922 setMeteredNetworkWhitelist(uid, isWhitelisted);
Felipe Leme70c57c22016-03-29 10:45:13 -07003923 } else {
Felipe Leme781ba142016-05-09 16:24:48 -07003924 // All scenarios should have been covered above.
Felipe Leme46c4fc32016-05-04 09:21:43 -07003925 Log.wtf(TAG, "Unexpected change of metered UID state for " + uid
3926 + ": foreground=" + isForeground
Felipe Leme781ba142016-05-09 16:24:48 -07003927 + ", whitelisted=" + isWhitelisted
3928 + ", blacklisted=" + isBlacklisted
Sudheer Shanka04d61ae2018-01-17 12:16:57 -08003929 + ", isRestrictedByAdmin=" + isRestrictedByAdmin
Felipe Lemed31a97f2016-05-06 14:53:50 -07003930 + ", newRule=" + uidRulesToString(newUidRules)
3931 + ", oldRule=" + uidRulesToString(oldUidRules));
Felipe Leme70c57c22016-03-29 10:45:13 -07003932 }
Felipe Leme781ba142016-05-09 16:24:48 -07003933
Sudheer Shankac9d94072017-02-22 22:13:55 +00003934 // Dispatch changed rule to existing listeners.
3935 mHandler.obtainMessage(MSG_RULES_CHANGED, uid, newUidRules).sendToTarget();
Felipe Leme781ba142016-05-09 16:24:48 -07003936 }
3937 }
3938
3939 /**
3940 * Updates the power-related part of the {@link #mUidRules} for a given map, and notify external
3941 * listeners in case of change.
3942 * <p>
3943 * There are 3 power-related rules that affects whether an app has background access on
3944 * non-metered networks, and when the condition applies and the UID is not whitelisted for power
3945 * restriction, it's added to the equivalent firewall chain:
3946 * <ul>
3947 * <li>App is idle: {@code fw_standby} firewall chain.
3948 * <li>Device is idle: {@code fw_dozable} firewall chain.
3949 * <li>Battery Saver Mode is on: {@code fw_powersave} firewall chain.
3950 * </ul>
3951 * <p>
3952 * This method updates the power-related part of the {@link #mUidRules} for a given uid based on
3953 * these modes, the UID process state (foreground or not), and the UIDwhitelist state.
3954 * <p>
3955 * <strong>NOTE: </strong>This method does not update the firewall rules on {@code netd}.
3956 */
Sudheer Shankac9d94072017-02-22 22:13:55 +00003957 private void updateRulesForPowerRestrictionsUL(int uid) {
Amith Yamasani0938f2f2016-09-16 12:46:31 -07003958 final int oldUidRules = mUidRules.get(uid, RULE_NONE);
3959
Sudheer Shankac9d94072017-02-22 22:13:55 +00003960 final int newUidRules = updateRulesForPowerRestrictionsUL(uid, oldUidRules, false);
Amith Yamasani0938f2f2016-09-16 12:46:31 -07003961
Sudheer Shankac9d94072017-02-22 22:13:55 +00003962 if (newUidRules == RULE_NONE) {
Amith Yamasani0938f2f2016-09-16 12:46:31 -07003963 mUidRules.delete(uid);
3964 } else {
Sudheer Shankac9d94072017-02-22 22:13:55 +00003965 mUidRules.put(uid, newUidRules);
Amith Yamasani0938f2f2016-09-16 12:46:31 -07003966 }
3967 }
3968
3969 /**
3970 * Similar to above but ignores idle state if app standby is currently disabled by parole.
3971 *
3972 * @param uid the uid of the app to update rules for
3973 * @param oldUidRules the current rules for the uid, in order to determine if there's a change
3974 * @param paroled whether to ignore idle state of apps and only look at other restrictions.
3975 *
Sudheer Shankac9d94072017-02-22 22:13:55 +00003976 * @return the new computed rules for the uid
Amith Yamasani0938f2f2016-09-16 12:46:31 -07003977 */
Sudheer Shankac9d94072017-02-22 22:13:55 +00003978 private int updateRulesForPowerRestrictionsUL(int uid, int oldUidRules, boolean paroled) {
Makoto Onuki0e6e3bd2017-03-20 14:53:00 -07003979 if (Trace.isTagEnabled(Trace.TRACE_TAG_NETWORK)) {
3980 Trace.traceBegin(Trace.TRACE_TAG_NETWORK,
3981 "updateRulesForPowerRestrictionsUL: " + uid + "/" + oldUidRules + "/"
3982 + (paroled ? "P" : "-"));
3983 }
3984 try {
3985 return updateRulesForPowerRestrictionsULInner(uid, oldUidRules, paroled);
3986 } finally {
3987 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
3988 }
3989 }
3990
3991 private int updateRulesForPowerRestrictionsULInner(int uid, int oldUidRules, boolean paroled) {
Felipe Leme781ba142016-05-09 16:24:48 -07003992 if (!isUidValidForBlacklistRules(uid)) {
3993 if (LOGD) Slog.d(TAG, "no need to update restrict power rules for uid " + uid);
Sudheer Shankac9d94072017-02-22 22:13:55 +00003994 return RULE_NONE;
Felipe Lemed31a97f2016-05-06 14:53:50 -07003995 }
Felipe Lemef28983d2016-03-25 12:18:23 -07003996
Amith Yamasani0938f2f2016-09-16 12:46:31 -07003997 final boolean isIdle = !paroled && isUidIdle(uid);
Felipe Leme781ba142016-05-09 16:24:48 -07003998 final boolean restrictMode = isIdle || mRestrictPower || mDeviceIdleMode;
Felipe Lemef0823852016-06-08 13:43:08 -07003999 final boolean isForeground = isUidForegroundOnRestrictPowerUL(uid);
Felipe Leme781ba142016-05-09 16:24:48 -07004000
Sudheer Shanka54a92fd2017-04-26 10:43:23 -07004001 final boolean isWhitelisted = isWhitelistedBatterySaverUL(uid, mDeviceIdleMode);
Felipe Leme781ba142016-05-09 16:24:48 -07004002 final int oldRule = oldUidRules & MASK_ALL_NETWORKS;
4003 int newRule = RULE_NONE;
4004
4005 // First step: define the new rule based on user restrictions and foreground state.
4006
4007 // NOTE: if statements below could be inlined, but it's easier to understand the logic
4008 // by considering the foreground and non-foreground states.
4009 if (isForeground) {
4010 if (restrictMode) {
4011 newRule = RULE_ALLOW_ALL;
4012 }
4013 } else if (restrictMode) {
4014 newRule = isWhitelisted ? RULE_ALLOW_ALL : RULE_REJECT_ALL;
4015 }
4016
4017 final int newUidRules = (oldUidRules & MASK_METERED_NETWORKS) | newRule;
4018
4019 if (LOGV) {
Felipe Leme88f40ad2016-08-10 13:00:32 -07004020 Log.v(TAG, "updateRulesForPowerRestrictionsUL(" + uid + ")"
Felipe Leme781ba142016-05-09 16:24:48 -07004021 + ", isIdle: " + isIdle
4022 + ", mRestrictPower: " + mRestrictPower
4023 + ", mDeviceIdleMode: " + mDeviceIdleMode
4024 + ", isForeground=" + isForeground
4025 + ", isWhitelisted=" + isWhitelisted
4026 + ", oldRule=" + uidRulesToString(oldRule)
4027 + ", newRule=" + uidRulesToString(newRule)
4028 + ", newUidRules=" + uidRulesToString(newUidRules)
4029 + ", oldUidRules=" + uidRulesToString(oldUidRules));
4030 }
4031
Felipe Leme781ba142016-05-09 16:24:48 -07004032 // Second step: notify listeners if state changed.
4033 if (newRule != oldRule) {
Hugo Benichi2966c182017-03-28 17:17:13 +09004034 if (newRule == RULE_NONE || hasRule(newRule, RULE_ALLOW_ALL)) {
Felipe Lemed31a97f2016-05-06 14:53:50 -07004035 if (LOGV) Log.v(TAG, "Allowing non-metered access for UID " + uid);
Hugo Benichi2966c182017-03-28 17:17:13 +09004036 } else if (hasRule(newRule, RULE_REJECT_ALL)) {
Felipe Lemed31a97f2016-05-06 14:53:50 -07004037 if (LOGV) Log.v(TAG, "Rejecting non-metered access for UID " + uid);
4038 } else {
4039 // All scenarios should have been covered above
4040 Log.wtf(TAG, "Unexpected change of non-metered UID state for " + uid
4041 + ": foreground=" + isForeground
Felipe Leme781ba142016-05-09 16:24:48 -07004042 + ", whitelisted=" + isWhitelisted
Felipe Lemed31a97f2016-05-06 14:53:50 -07004043 + ", newRule=" + uidRulesToString(newUidRules)
4044 + ", oldRule=" + uidRulesToString(oldUidRules));
4045 }
Sudheer Shankac9d94072017-02-22 22:13:55 +00004046 mHandler.obtainMessage(MSG_RULES_CHANGED, uid, newUidRules).sendToTarget();
Amith Yamasani15e472352015-04-24 19:06:07 -07004047 }
Amith Yamasani0938f2f2016-09-16 12:46:31 -07004048
Sudheer Shankac9d94072017-02-22 22:13:55 +00004049 return newUidRules;
Jeff Sharkey4414cea2011-06-24 17:05:24 -07004050 }
4051
Xiaohui Chen8dca36d2015-06-19 12:44:59 -07004052 private class AppIdleStateChangeListener
4053 extends UsageStatsManagerInternal.AppIdleStateChangeListener {
4054
4055 @Override
Amith Yamasani119be9a2018-02-18 22:23:00 -08004056 public void onAppIdleStateChanged(String packageName, int userId, boolean idle, int bucket,
4057 int reason) {
Xiaohui Chen8dca36d2015-06-19 12:44:59 -07004058 try {
Jeff Sharkeyc5967e92016-01-07 18:50:29 -07004059 final int uid = mContext.getPackageManager().getPackageUidAsUser(packageName,
4060 PackageManager.MATCH_UNINSTALLED_PACKAGES, userId);
Felipe Lemef0823852016-06-08 13:43:08 -07004061 synchronized (mUidRulesFirstLock) {
Sudheer Shanka352dc572017-09-22 17:09:38 -07004062 mLogger.appIdleStateChanged(uid, idle);
Felipe Lemef0823852016-06-08 13:43:08 -07004063 updateRuleForAppIdleUL(uid);
Sudheer Shankac9d94072017-02-22 22:13:55 +00004064 updateRulesForPowerRestrictionsUL(uid);
Xiaohui Chen8dca36d2015-06-19 12:44:59 -07004065 }
4066 } catch (NameNotFoundException nnfe) {
Amith Yamasani15e472352015-04-24 19:06:07 -07004067 }
Xiaohui Chen8dca36d2015-06-19 12:44:59 -07004068 }
4069
4070 @Override
4071 public void onParoleStateChanged(boolean isParoleOn) {
Felipe Lemef0823852016-06-08 13:43:08 -07004072 synchronized (mUidRulesFirstLock) {
Sudheer Shanka352dc572017-09-22 17:09:38 -07004073 mLogger.paroleStateChanged(isParoleOn);
Felipe Lemef0823852016-06-08 13:43:08 -07004074 updateRulesForAppIdleParoleUL();
Xiaohui Chen8dca36d2015-06-19 12:44:59 -07004075 }
Amith Yamasani15e472352015-04-24 19:06:07 -07004076 }
4077 }
4078
Jeff Sharkey1b6519b2016-04-28 15:33:18 -06004079 private void dispatchUidRulesChanged(INetworkPolicyListener listener, int uid, int uidRules) {
4080 if (listener != null) {
4081 try {
4082 listener.onUidRulesChanged(uid, uidRules);
4083 } catch (RemoteException ignored) {
4084 }
4085 }
4086 }
4087
4088 private void dispatchMeteredIfacesChanged(INetworkPolicyListener listener,
4089 String[] meteredIfaces) {
4090 if (listener != null) {
4091 try {
4092 listener.onMeteredIfacesChanged(meteredIfaces);
4093 } catch (RemoteException ignored) {
4094 }
4095 }
4096 }
4097
4098 private void dispatchRestrictBackgroundChanged(INetworkPolicyListener listener,
4099 boolean restrictBackground) {
4100 if (listener != null) {
4101 try {
4102 listener.onRestrictBackgroundChanged(restrictBackground);
4103 } catch (RemoteException ignored) {
4104 }
4105 }
4106 }
4107
Felipe Leme0ecfcd12016-09-06 12:49:48 -07004108 private void dispatchUidPoliciesChanged(INetworkPolicyListener listener, int uid,
4109 int uidPolicies) {
Jeff Sharkey1b6519b2016-04-28 15:33:18 -06004110 if (listener != null) {
4111 try {
Felipe Leme0ecfcd12016-09-06 12:49:48 -07004112 listener.onUidPoliciesChanged(uid, uidPolicies);
Felipe Leme99d5d3d2016-05-16 13:30:57 -07004113 } catch (RemoteException ignored) {
4114 }
4115 }
4116 }
4117
Jeff Sharkey9252b342018-01-19 07:58:35 +09004118 private void dispatchSubscriptionOverride(INetworkPolicyListener listener, int subId,
4119 int overrideMask, int overrideValue) {
4120 if (listener != null) {
4121 try {
4122 listener.onSubscriptionOverride(subId, overrideMask, overrideValue);
4123 } catch (RemoteException ignored) {
4124 }
4125 }
4126 }
4127
Makoto Onuki8e777332017-03-28 11:25:47 -07004128 private final Handler.Callback mHandlerCallback = new Handler.Callback() {
Jeff Sharkeybfdd6802012-04-09 10:49:19 -07004129 @Override
Jeff Sharkey4414cea2011-06-24 17:05:24 -07004130 public boolean handleMessage(Message msg) {
4131 switch (msg.what) {
4132 case MSG_RULES_CHANGED: {
4133 final int uid = msg.arg1;
4134 final int uidRules = msg.arg2;
Sudheer Shankac9d94072017-02-22 22:13:55 +00004135 final int length = mListeners.beginBroadcast();
4136 for (int i = 0; i < length; i++) {
4137 final INetworkPolicyListener listener = mListeners.getBroadcastItem(i);
4138 dispatchUidRulesChanged(listener, uid, uidRules);
Jeff Sharkey4414cea2011-06-24 17:05:24 -07004139 }
Sudheer Shankac9d94072017-02-22 22:13:55 +00004140 mListeners.finishBroadcast();
Jeff Sharkey4414cea2011-06-24 17:05:24 -07004141 return true;
4142 }
4143 case MSG_METERED_IFACES_CHANGED: {
4144 final String[] meteredIfaces = (String[]) msg.obj;
4145 final int length = mListeners.beginBroadcast();
4146 for (int i = 0; i < length; i++) {
4147 final INetworkPolicyListener listener = mListeners.getBroadcastItem(i);
Jeff Sharkey1b6519b2016-04-28 15:33:18 -06004148 dispatchMeteredIfacesChanged(listener, meteredIfaces);
Jeff Sharkey4414cea2011-06-24 17:05:24 -07004149 }
4150 mListeners.finishBroadcast();
4151 return true;
4152 }
Jeff Sharkey7e25b0e2011-11-08 15:43:12 -08004153 case MSG_LIMIT_REACHED: {
4154 final String iface = (String) msg.obj;
4155
Felipe Lemef0823852016-06-08 13:43:08 -07004156 synchronized (mNetworkPoliciesSecondLock) {
Jeff Sharkey7e25b0e2011-11-08 15:43:12 -08004157 if (mMeteredIfaces.contains(iface)) {
Jeff Sharkeye0c29952018-02-20 17:24:55 -07004158 // force stats update to make sure we have
4159 // numbers that caused alert to trigger.
4160 mNetworkStats.forceUpdate();
Jeff Sharkey7e25b0e2011-11-08 15:43:12 -08004161
Felipe Lemef0823852016-06-08 13:43:08 -07004162 updateNetworkEnabledNL();
4163 updateNotificationsNL();
Jeff Sharkey7e25b0e2011-11-08 15:43:12 -08004164 }
4165 }
4166 return true;
4167 }
Jeff Sharkey1f8ea2d2012-02-07 12:05:43 -08004168 case MSG_RESTRICT_BACKGROUND_CHANGED: {
4169 final boolean restrictBackground = msg.arg1 != 0;
4170 final int length = mListeners.beginBroadcast();
4171 for (int i = 0; i < length; i++) {
4172 final INetworkPolicyListener listener = mListeners.getBroadcastItem(i);
Jeff Sharkey1b6519b2016-04-28 15:33:18 -06004173 dispatchRestrictBackgroundChanged(listener, restrictBackground);
Jeff Sharkey1f8ea2d2012-02-07 12:05:43 -08004174 }
4175 mListeners.finishBroadcast();
Felipe Leme9778f762016-01-27 14:46:39 -08004176 final Intent intent =
4177 new Intent(ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED);
4178 intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
4179 mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
4180 return true;
4181 }
Felipe Leme0ecfcd12016-09-06 12:49:48 -07004182 case MSG_POLICIES_CHANGED: {
Felipe Leme9778f762016-01-27 14:46:39 -08004183 final int uid = msg.arg1;
Felipe Leme0ecfcd12016-09-06 12:49:48 -07004184 final int policy = msg.arg2;
Felipe Leme57e3d312016-08-23 14:42:52 -07004185 final Boolean notifyApp = (Boolean) msg.obj;
Jeff Sharkey1b6519b2016-04-28 15:33:18 -06004186 // First notify internal listeners...
Felipe Leme57e3d312016-08-23 14:42:52 -07004187 final int length = mListeners.beginBroadcast();
4188 for (int i = 0; i < length; i++) {
4189 final INetworkPolicyListener listener = mListeners.getBroadcastItem(i);
Felipe Leme0ecfcd12016-09-06 12:49:48 -07004190 dispatchUidPoliciesChanged(listener, uid, policy);
Felipe Leme99d5d3d2016-05-16 13:30:57 -07004191 }
4192 mListeners.finishBroadcast();
Felipe Leme57e3d312016-08-23 14:42:52 -07004193 // ...then apps listening to ACTION_RESTRICT_BACKGROUND_CHANGED
4194 if (notifyApp.booleanValue()) {
4195 broadcastRestrictBackgroundChanged(uid, notifyApp);
4196 }
Felipe Leme99d5d3d2016-05-16 13:30:57 -07004197 return true;
4198 }
Jeff Sharkeye19f39b2012-05-24 10:21:16 -07004199 case MSG_ADVISE_PERSIST_THRESHOLD: {
4200 final long lowestRule = (Long) msg.obj;
Jeff Sharkeye0c29952018-02-20 17:24:55 -07004201 // make sure stats are recorded frequently enough; we aim
4202 // for 2MB threshold for 2GB/month rules.
4203 final long persistThreshold = lowestRule / 1000;
4204 mNetworkStats.advisePersistThreshold(persistThreshold);
Jeff Sharkeye19f39b2012-05-24 10:21:16 -07004205 return true;
Jeff Sharkey1f8ea2d2012-02-07 12:05:43 -08004206 }
Amith Yamasani3646cbd2016-04-13 14:04:53 -07004207 case MSG_UPDATE_INTERFACE_QUOTA: {
4208 removeInterfaceQuota((String) msg.obj);
4209 // int params need to be stitched back into a long
4210 setInterfaceQuota((String) msg.obj,
4211 ((long) msg.arg1 << 32) | (msg.arg2 & 0xFFFFFFFFL));
4212 return true;
4213 }
4214 case MSG_REMOVE_INTERFACE_QUOTA: {
4215 removeInterfaceQuota((String) msg.obj);
4216 return true;
4217 }
Felipe Leme03e95e22016-09-09 09:25:31 -07004218 case MSG_RESET_FIREWALL_RULES_BY_UID: {
4219 resetUidFirewallRules(msg.arg1);
4220 return true;
4221 }
Jeff Sharkey9252b342018-01-19 07:58:35 +09004222 case MSG_SUBSCRIPTION_OVERRIDE: {
4223 final int overrideMask = msg.arg1;
4224 final int overrideValue = msg.arg2;
4225 final int subId = (int) msg.obj;
4226 final int length = mListeners.beginBroadcast();
4227 for (int i = 0; i < length; i++) {
4228 final INetworkPolicyListener listener = mListeners.getBroadcastItem(i);
4229 dispatchSubscriptionOverride(listener, subId, overrideMask, overrideValue);
4230 }
4231 mListeners.finishBroadcast();
4232 return true;
4233 }
Sudheer Shanka04d61ae2018-01-17 12:16:57 -08004234 case MSG_METERED_RESTRICTED_PACKAGES_CHANGED: {
4235 final int userId = msg.arg1;
4236 final Set<String> packageNames = (Set<String>) msg.obj;
4237 setMeteredRestrictedPackagesInternal(packageNames, userId);
4238 return true;
4239 }
Makoto Onuki3f1bf5f2018-04-04 15:29:00 -07004240 case MSG_SET_NETWORK_TEMPLATE_ENABLED: {
4241 final NetworkTemplate template = (NetworkTemplate) msg.obj;
4242 final boolean enabled = msg.arg1 != 0;
4243 setNetworkTemplateEnabledInner(template, enabled);
4244 return true;
4245 }
Jeff Sharkey4414cea2011-06-24 17:05:24 -07004246 default: {
4247 return false;
Jeff Sharkeyaf11d482011-06-13 00:14:31 -07004248 }
4249 }
4250 }
Makoto Onuki8e777332017-03-28 11:25:47 -07004251 };
4252
4253 private final Handler.Callback mUidEventHandlerCallback = new Handler.Callback() {
4254 @Override
4255 public boolean handleMessage(Message msg) {
4256 switch (msg.what) {
4257 case UID_MSG_STATE_CHANGED: {
4258 final int uid = msg.arg1;
4259 final int procState = msg.arg2;
4260 final long procStateSeq = (Long) msg.obj;
4261
4262 handleUidChanged(uid, procState, procStateSeq);
4263 return true;
4264 }
4265 case UID_MSG_GONE: {
4266 final int uid = msg.arg1;
4267 handleUidGone(uid);
4268 return true;
4269 }
4270 default: {
4271 return false;
4272 }
4273 }
4274 }
Felipe Leme57e3d312016-08-23 14:42:52 -07004275
Jeff Sharkey4414cea2011-06-24 17:05:24 -07004276 };
Jeff Sharkey22c055e2011-06-12 21:13:51 -07004277
Makoto Onuki8e777332017-03-28 11:25:47 -07004278 void handleUidChanged(int uid, int procState, long procStateSeq) {
4279 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "onUidStateChanged");
4280 try {
4281 synchronized (mUidRulesFirstLock) {
4282 // We received a uid state change callback, add it to the history so that it
4283 // will be useful for debugging.
Sudheer Shanka352dc572017-09-22 17:09:38 -07004284 mLogger.uidStateChanged(uid, procState, procStateSeq);
Makoto Onuki8e777332017-03-28 11:25:47 -07004285 // Now update the network policy rules as per the updated uid state.
4286 updateUidStateUL(uid, procState);
4287 // Updating the network rules is done, so notify AMS about this.
4288 mActivityManagerInternal.notifyNetworkPolicyRulesUpdated(uid, procStateSeq);
4289 }
4290 } finally {
4291 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
4292 }
4293 }
4294
4295 void handleUidGone(int uid) {
4296 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "onUidGone");
4297 try {
4298 synchronized (mUidRulesFirstLock) {
4299 removeUidStateUL(uid);
4300 }
4301 } finally {
4302 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
4303 }
4304 }
4305
Felipe Leme57e3d312016-08-23 14:42:52 -07004306 private void broadcastRestrictBackgroundChanged(int uid, Boolean changed) {
4307 final PackageManager pm = mContext.getPackageManager();
4308 final String[] packages = pm.getPackagesForUid(uid);
4309 if (packages != null) {
4310 final int userId = UserHandle.getUserId(uid);
4311 for (String packageName : packages) {
4312 final Intent intent =
4313 new Intent(ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED);
4314 intent.setPackage(packageName);
4315 intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
4316 mContext.sendBroadcastAsUser(intent, UserHandle.of(userId));
4317 }
4318 }
4319 }
4320
Jeff Sharkey64c96ec2017-08-30 16:28:26 -06004321 private void setInterfaceQuotaAsync(String iface, long quotaBytes) {
4322 // long quotaBytes split up into two ints to fit in message
4323 mHandler.obtainMessage(MSG_UPDATE_INTERFACE_QUOTA, (int) (quotaBytes >> 32),
4324 (int) (quotaBytes & 0xFFFFFFFF), iface).sendToTarget();
4325 }
4326
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07004327 private void setInterfaceQuota(String iface, long quotaBytes) {
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07004328 try {
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07004329 mNetworkManager.setInterfaceQuota(iface, quotaBytes);
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07004330 } catch (IllegalStateException e) {
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07004331 Log.wtf(TAG, "problem setting interface quota", e);
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07004332 } catch (RemoteException e) {
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07004333 // ignored; service lives in system_server
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07004334 }
4335 }
4336
Jeff Sharkey64c96ec2017-08-30 16:28:26 -06004337 private void removeInterfaceQuotaAsync(String iface) {
4338 mHandler.obtainMessage(MSG_REMOVE_INTERFACE_QUOTA, iface).sendToTarget();
4339 }
4340
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07004341 private void removeInterfaceQuota(String iface) {
4342 try {
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07004343 mNetworkManager.removeInterfaceQuota(iface);
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07004344 } catch (IllegalStateException e) {
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07004345 Log.wtf(TAG, "problem removing interface quota", e);
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07004346 } catch (RemoteException e) {
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07004347 // ignored; service lives in system_server
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07004348 }
4349 }
4350
Felipe Leme70c57c22016-03-29 10:45:13 -07004351 private void setMeteredNetworkBlacklist(int uid, boolean enable) {
4352 if (LOGV) Slog.v(TAG, "setMeteredNetworkBlacklist " + uid + ": " + enable);
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07004353 try {
Felipe Leme70c57c22016-03-29 10:45:13 -07004354 mNetworkManager.setUidMeteredNetworkBlacklist(uid, enable);
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07004355 } catch (IllegalStateException e) {
Felipe Leme70c57c22016-03-29 10:45:13 -07004356 Log.wtf(TAG, "problem setting blacklist (" + enable + ") rules for " + uid, e);
4357 } catch (RemoteException e) {
4358 // ignored; service lives in system_server
4359 }
4360 }
4361
4362 private void setMeteredNetworkWhitelist(int uid, boolean enable) {
4363 if (LOGV) Slog.v(TAG, "setMeteredNetworkWhitelist " + uid + ": " + enable);
4364 try {
4365 mNetworkManager.setUidMeteredNetworkWhitelist(uid, enable);
4366 } catch (IllegalStateException e) {
4367 Log.wtf(TAG, "problem setting whitelist (" + enable + ") rules for " + uid, e);
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07004368 } catch (RemoteException e) {
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07004369 // ignored; service lives in system_server
Jeff Sharkeyb3f19ca2011-06-29 23:54:13 -07004370 }
4371 }
4372
Felipe Lemebc853dd2016-09-08 13:26:55 -07004373 private static final int CHAIN_TOGGLE_NONE = 0;
4374 private static final int CHAIN_TOGGLE_ENABLE = 1;
4375 private static final int CHAIN_TOGGLE_DISABLE = 2;
4376 @Retention(RetentionPolicy.SOURCE)
4377 @IntDef(flag = false, value = {
4378 CHAIN_TOGGLE_NONE,
4379 CHAIN_TOGGLE_ENABLE,
4380 CHAIN_TOGGLE_DISABLE
4381 })
4382 public @interface ChainToggleType {
4383 }
4384
4385 /**
4386 * Calls {@link #setUidFirewallRules(int, SparseIntArray)} and
Sudheer Shankaaddebcc2017-10-03 09:43:20 -07004387 * {@link #enableFirewallChainUL(int, boolean)} synchronously.
Felipe Lemebc853dd2016-09-08 13:26:55 -07004388 *
4389 * @param chain firewall chain.
4390 * @param uidRules new UID rules; if {@code null}, only toggles chain state.
4391 * @param toggle whether the chain should be enabled, disabled, or not changed.
4392 */
Sudheer Shankaaddebcc2017-10-03 09:43:20 -07004393 private void setUidFirewallRulesUL(int chain, @Nullable SparseIntArray uidRules,
Felipe Lemebc853dd2016-09-08 13:26:55 -07004394 @ChainToggleType int toggle) {
Sudheer Shankaaddebcc2017-10-03 09:43:20 -07004395 if (uidRules != null) {
4396 setUidFirewallRulesUL(chain, uidRules);
4397 }
4398 if (toggle != CHAIN_TOGGLE_NONE) {
4399 enableFirewallChainUL(chain, toggle == CHAIN_TOGGLE_ENABLE);
4400 }
Felipe Lemebc853dd2016-09-08 13:26:55 -07004401 }
4402
Amith Yamasani15e472352015-04-24 19:06:07 -07004403 /**
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07004404 * Set uid rules on a particular firewall chain. This is going to synchronize the rules given
4405 * here to netd. It will clean up dead rules and make sure the target chain only contains rules
4406 * specified here.
Amith Yamasani15e472352015-04-24 19:06:07 -07004407 */
Sudheer Shankaaddebcc2017-10-03 09:43:20 -07004408 private void setUidFirewallRulesUL(int chain, SparseIntArray uidRules) {
Amith Yamasani15e472352015-04-24 19:06:07 -07004409 try {
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07004410 int size = uidRules.size();
4411 int[] uids = new int[size];
4412 int[] rules = new int[size];
4413 for(int index = size - 1; index >= 0; --index) {
4414 uids[index] = uidRules.keyAt(index);
4415 rules[index] = uidRules.valueAt(index);
4416 }
4417 mNetworkManager.setFirewallUidRules(chain, uids, rules);
Sudheer Shanka352dc572017-09-22 17:09:38 -07004418 mLogger.firewallRulesChanged(chain, uids, rules);
Amith Yamasani15e472352015-04-24 19:06:07 -07004419 } catch (IllegalStateException e) {
4420 Log.wtf(TAG, "problem setting firewall uid rules", e);
4421 } catch (RemoteException e) {
4422 // ignored; service lives in system_server
4423 }
4424 }
4425
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07004426 /**
4427 * Add or remove a uid to the firewall blacklist for all network ifaces.
4428 */
Dianne Hackborn4a503b12015-08-06 22:19:06 -07004429 private void setUidFirewallRule(int chain, int uid, int rule) {
Makoto Onuki0e6e3bd2017-03-20 14:53:00 -07004430 if (Trace.isTagEnabled(Trace.TRACE_TAG_NETWORK)) {
4431 Trace.traceBegin(Trace.TRACE_TAG_NETWORK,
4432 "setUidFirewallRule: " + chain + "/" + uid + "/" + rule);
Jeff Sharkeydc988062015-09-14 10:09:47 -07004433 }
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07004434 try {
Makoto Onuki0e6e3bd2017-03-20 14:53:00 -07004435 if (chain == FIREWALL_CHAIN_DOZABLE) {
4436 mUidFirewallDozableRules.put(uid, rule);
4437 } else if (chain == FIREWALL_CHAIN_STANDBY) {
4438 mUidFirewallStandbyRules.put(uid, rule);
4439 } else if (chain == FIREWALL_CHAIN_POWERSAVE) {
4440 mUidFirewallPowerSaveRules.put(uid, rule);
4441 }
4442
4443 try {
4444 mNetworkManager.setFirewallUidRule(chain, uid, rule);
Sudheer Shanka352dc572017-09-22 17:09:38 -07004445 mLogger.uidFirewallRuleChanged(chain, uid, rule);
Makoto Onuki0e6e3bd2017-03-20 14:53:00 -07004446 } catch (IllegalStateException e) {
4447 Log.wtf(TAG, "problem setting firewall uid rules", e);
4448 } catch (RemoteException e) {
4449 // ignored; service lives in system_server
4450 }
4451 } finally {
4452 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07004453 }
4454 }
4455
4456 /**
4457 * Add or remove a uid to the firewall blacklist for all network ifaces.
4458 */
Felipe Lemef0823852016-06-08 13:43:08 -07004459 private void enableFirewallChainUL(int chain, boolean enable) {
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07004460 if (mFirewallChainStates.indexOfKey(chain) >= 0 &&
4461 mFirewallChainStates.get(chain) == enable) {
4462 // All is the same, nothing to do.
4463 return;
4464 }
Xiaohui Chen8dca36d2015-06-19 12:44:59 -07004465 mFirewallChainStates.put(chain, enable);
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07004466 try {
4467 mNetworkManager.setFirewallChainEnabled(chain, enable);
Sudheer Shanka352dc572017-09-22 17:09:38 -07004468 mLogger.firewallChainEnabled(chain, enable);
Xiaohui Chenb41c9f72015-06-17 15:55:37 -07004469 } catch (IllegalStateException e) {
4470 Log.wtf(TAG, "problem enable firewall chain", e);
4471 } catch (RemoteException e) {
4472 // ignored; service lives in system_server
4473 }
4474 }
4475
Felipe Leme03e95e22016-09-09 09:25:31 -07004476 /**
4477 * Resets all firewall rules associated with an UID.
4478 */
4479 private void resetUidFirewallRules(int uid) {
4480 try {
4481 mNetworkManager.setFirewallUidRule(FIREWALL_CHAIN_DOZABLE, uid, FIREWALL_RULE_DEFAULT);
4482 mNetworkManager.setFirewallUidRule(FIREWALL_CHAIN_STANDBY, uid, FIREWALL_RULE_DEFAULT);
4483 mNetworkManager
4484 .setFirewallUidRule(FIREWALL_CHAIN_POWERSAVE, uid, FIREWALL_RULE_DEFAULT);
4485 mNetworkManager.setUidMeteredNetworkWhitelist(uid, false);
4486 mNetworkManager.setUidMeteredNetworkBlacklist(uid, false);
4487 } catch (IllegalStateException e) {
4488 Log.wtf(TAG, "problem resetting firewall uid rules for " + uid, e);
4489 } catch (RemoteException e) {
4490 // ignored; service lives in system_server
4491 }
4492 }
4493
Jeff Sharkeye0c29952018-02-20 17:24:55 -07004494 @Deprecated
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07004495 private long getTotalBytes(NetworkTemplate template, long start, long end) {
Jeff Sharkeye0c29952018-02-20 17:24:55 -07004496 return getNetworkTotalBytes(template, start, end);
4497 }
4498
4499 private long getNetworkTotalBytes(NetworkTemplate template, long start, long end) {
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07004500 try {
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -07004501 return mNetworkStats.getNetworkTotalBytes(template, start, end);
Jeff Sharkey63abc372012-01-11 18:38:16 -08004502 } catch (RuntimeException e) {
Jeff Sharkeye0c29952018-02-20 17:24:55 -07004503 Slog.w(TAG, "Failed to read network stats: " + e);
Jeff Sharkey63abc372012-01-11 18:38:16 -08004504 return 0;
Jeff Sharkeye0c29952018-02-20 17:24:55 -07004505 }
4506 }
4507
4508 private NetworkStats getNetworkUidBytes(NetworkTemplate template, long start, long end) {
4509 try {
4510 return mNetworkStats.getNetworkUidBytes(template, start, end);
4511 } catch (RuntimeException e) {
4512 Slog.w(TAG, "Failed to read network stats: " + e);
4513 return new NetworkStats(SystemClock.elapsedRealtime(), 0);
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07004514 }
4515 }
4516
Jeff Sharkey8c1dc722012-05-04 14:49:37 -07004517 private boolean isBandwidthControlEnabled() {
4518 final long token = Binder.clearCallingIdentity();
4519 try {
4520 return mNetworkManager.isBandwidthControlEnabled();
4521 } catch (RemoteException e) {
4522 // ignored; service lives in system_server
4523 return false;
4524 } finally {
4525 Binder.restoreCallingIdentity(token);
4526 }
4527 }
4528
Jeff Sharkey3a844fc2011-08-16 14:37:57 -07004529 private static Intent buildAllowBackgroundDataIntent() {
4530 return new Intent(ACTION_ALLOW_BACKGROUND);
4531 }
4532
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -08004533 private static Intent buildSnoozeWarningIntent(NetworkTemplate template) {
4534 final Intent intent = new Intent(ACTION_SNOOZE_WARNING);
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07004535 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
4536 intent.putExtra(EXTRA_NETWORK_TEMPLATE, template);
4537 return intent;
4538 }
4539
4540 private static Intent buildSnoozeRapidIntent(NetworkTemplate template) {
4541 final Intent intent = new Intent(ACTION_SNOOZE_RAPID);
4542 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
Jeff Sharkey0e2e5f82012-02-02 16:02:51 -08004543 intent.putExtra(EXTRA_NETWORK_TEMPLATE, template);
4544 return intent;
4545 }
4546
Wei Liu546cb772016-07-21 16:19:01 -07004547 private static Intent buildNetworkOverLimitIntent(Resources res, NetworkTemplate template) {
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07004548 final Intent intent = new Intent();
Wei Liu546cb772016-07-21 16:19:01 -07004549 intent.setComponent(ComponentName.unflattenFromString(
4550 res.getString(R.string.config_networkOverLimitComponent)));
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07004551 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4552 intent.putExtra(EXTRA_NETWORK_TEMPLATE, template);
4553 return intent;
4554 }
4555
Wei Liu546cb772016-07-21 16:19:01 -07004556 private static Intent buildViewDataUsageIntent(Resources res, NetworkTemplate template) {
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07004557 final Intent intent = new Intent();
Wei Liu546cb772016-07-21 16:19:01 -07004558 intent.setComponent(ComponentName.unflattenFromString(
4559 res.getString(R.string.config_dataUsageSummaryComponent)));
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07004560 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4561 intent.putExtra(EXTRA_NETWORK_TEMPLATE, template);
4562 return intent;
4563 }
4564
Jeff Sharkey8b2c3a142012-11-12 11:45:05 -08004565 @VisibleForTesting
Jeff Sharkey163e6442011-10-31 16:37:52 -07004566 public void addIdleHandler(IdleHandler handler) {
4567 mHandler.getLooper().getQueue().addIdleHandler(handler);
4568 }
4569
jackqdyulei29c82ab2017-03-10 14:09:16 -08004570 @VisibleForTesting
4571 public void updateRestrictBackgroundByLowPowerModeUL(final PowerSaveState result) {
4572 mRestrictBackgroundPowerState = result;
4573
4574 boolean restrictBackground = result.batterySaverEnabled;
4575 boolean shouldInvokeRestrictBackground;
4576 // store the temporary mRestrictBackgroundChangedInBsm and update it at last
4577 boolean localRestrictBgChangedInBsm = mRestrictBackgroundChangedInBsm;
4578
4579 if (result.globalBatterySaverEnabled) {
4580 // Try to turn on restrictBackground if (1) it is off and (2) batter saver need to
4581 // turn it on.
4582 shouldInvokeRestrictBackground = !mRestrictBackground && result.batterySaverEnabled;
4583 mRestrictBackgroundBeforeBsm = mRestrictBackground;
4584 localRestrictBgChangedInBsm = false;
4585 } else {
4586 // Try to restore the restrictBackground if it doesn't change in bsm
4587 shouldInvokeRestrictBackground = !mRestrictBackgroundChangedInBsm;
4588 restrictBackground = mRestrictBackgroundBeforeBsm;
4589 }
4590
4591 if (shouldInvokeRestrictBackground) {
Sudheer Shanka543339f2017-07-28 15:18:07 -07004592 setRestrictBackgroundUL(restrictBackground);
jackqdyulei29c82ab2017-03-10 14:09:16 -08004593 }
4594
4595 // Change it at last so setRestrictBackground() won't affect this variable
4596 mRestrictBackgroundChangedInBsm = localRestrictBgChangedInBsm;
4597 }
4598
Jeff Sharkey1b861272011-05-22 00:34:52 -07004599 private static void collectKeys(SparseIntArray source, SparseBooleanArray target) {
4600 final int size = source.size();
4601 for (int i = 0; i < size; i++) {
4602 target.put(source.keyAt(i), true);
4603 }
4604 }
4605
Stuart Scottf1fb3972015-04-02 18:00:02 -07004606 @Override
4607 public void factoryReset(String subscriber) {
4608 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
4609
Stuart Scotte3e314d2015-04-20 14:07:45 -07004610 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_NETWORK_RESET)) {
4611 return;
4612 }
4613
Stuart Scottf1fb3972015-04-02 18:00:02 -07004614 // Turn mobile data limit off
Stuart Scott9a9a1d92015-04-20 11:33:06 -07004615 NetworkPolicy[] policies = getNetworkPolicies(mContext.getOpPackageName());
Stuart Scottf1fb3972015-04-02 18:00:02 -07004616 NetworkTemplate template = NetworkTemplate.buildTemplateMobileAll(subscriber);
4617 for (NetworkPolicy policy : policies) {
4618 if (policy.template.equals(template)) {
4619 policy.limitBytes = NetworkPolicy.LIMIT_DISABLED;
4620 policy.inferred = false;
4621 policy.clearSnooze();
4622 }
4623 }
4624 setNetworkPolicies(policies);
4625
4626 // Turn restrict background data off
4627 setRestrictBackground(false);
4628
Stuart Scotte3e314d2015-04-20 14:07:45 -07004629 if (!mUserManager.hasUserRestriction(UserManager.DISALLOW_APPS_CONTROL)) {
4630 // Remove app's "restrict background data" flag
4631 for (int uid : getUidsWithPolicy(POLICY_REJECT_METERED_BACKGROUND)) {
4632 setUidPolicy(uid, POLICY_NONE);
4633 }
Stuart Scottf1fb3972015-04-02 18:00:02 -07004634 }
4635 }
Felipe Lemeb85a6372016-01-14 16:16:16 -08004636
Sudheer Shankab8f23162017-08-04 13:30:10 -07004637 @Override
4638 public boolean isUidNetworkingBlocked(int uid, boolean isNetworkMetered) {
Makoto Onuki49392d32018-04-11 13:51:02 -07004639 final long startTime = mStatLogger.getTime();
4640
Sudheer Shankab8f23162017-08-04 13:30:10 -07004641 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
Makoto Onuki49392d32018-04-11 13:51:02 -07004642 final boolean ret = isUidNetworkingBlockedInternal(uid, isNetworkMetered);
4643
4644 mStatLogger.logDurationStat(Stats.IS_UID_NETWORKING_BLOCKED, startTime);
4645
4646 return ret;
Sudheer Shankab8f23162017-08-04 13:30:10 -07004647 }
4648
4649 private boolean isUidNetworkingBlockedInternal(int uid, boolean isNetworkMetered) {
4650 final int uidRules;
4651 final boolean isBackgroundRestricted;
4652 synchronized (mUidRulesFirstLock) {
4653 uidRules = mUidRules.get(uid, RULE_NONE);
4654 isBackgroundRestricted = mRestrictBackground;
4655 }
4656 if (hasRule(uidRules, RULE_REJECT_ALL)) {
Sudheer Shanka352dc572017-09-22 17:09:38 -07004657 mLogger.networkBlocked(uid, NTWK_BLOCKED_POWER);
Sudheer Shankab8f23162017-08-04 13:30:10 -07004658 return true;
4659 }
4660 if (!isNetworkMetered) {
Sudheer Shanka352dc572017-09-22 17:09:38 -07004661 mLogger.networkBlocked(uid, NTWK_ALLOWED_NON_METERED);
Sudheer Shankab8f23162017-08-04 13:30:10 -07004662 return false;
4663 }
4664 if (hasRule(uidRules, RULE_REJECT_METERED)) {
Sudheer Shanka352dc572017-09-22 17:09:38 -07004665 mLogger.networkBlocked(uid, NTWK_BLOCKED_BLACKLIST);
Sudheer Shankab8f23162017-08-04 13:30:10 -07004666 return true;
4667 }
4668 if (hasRule(uidRules, RULE_ALLOW_METERED)) {
Sudheer Shanka352dc572017-09-22 17:09:38 -07004669 mLogger.networkBlocked(uid, NTWK_ALLOWED_WHITELIST);
Sudheer Shankab8f23162017-08-04 13:30:10 -07004670 return false;
4671 }
4672 if (hasRule(uidRules, RULE_TEMPORARY_ALLOW_METERED)) {
Sudheer Shanka352dc572017-09-22 17:09:38 -07004673 mLogger.networkBlocked(uid, NTWK_ALLOWED_TMP_WHITELIST);
Sudheer Shankab8f23162017-08-04 13:30:10 -07004674 return false;
4675 }
4676 if (isBackgroundRestricted) {
Sudheer Shanka352dc572017-09-22 17:09:38 -07004677 mLogger.networkBlocked(uid, NTWK_BLOCKED_BG_RESTRICT);
Sudheer Shankab8f23162017-08-04 13:30:10 -07004678 return true;
4679 }
Sudheer Shanka352dc572017-09-22 17:09:38 -07004680 mLogger.networkBlocked(uid, NTWK_ALLOWED_DEFAULT);
Sudheer Shankab8f23162017-08-04 13:30:10 -07004681 return false;
4682 }
4683
Felipe Lemed17fda42016-04-29 11:12:45 -07004684 private class NetworkPolicyManagerInternalImpl extends NetworkPolicyManagerInternal {
4685
4686 @Override
4687 public void resetUserState(int userId) {
Felipe Lemef0823852016-06-08 13:43:08 -07004688 synchronized (mUidRulesFirstLock) {
4689 boolean changed = removeUserStateUL(userId, false);
4690 changed = addDefaultRestrictBackgroundWhitelistUidsUL(userId) || changed;
Felipe Lemed17fda42016-04-29 11:12:45 -07004691 if (changed) {
Felipe Lemef0823852016-06-08 13:43:08 -07004692 synchronized (mNetworkPoliciesSecondLock) {
4693 writePolicyAL();
4694 }
Felipe Lemed17fda42016-04-29 11:12:45 -07004695 }
4696 }
4697 }
Hugo Benichi938ab4f2017-02-11 17:04:43 +09004698
4699 /**
4700 * @return true if the given uid is restricted from doing networking on metered networks.
4701 */
4702 @Override
4703 public boolean isUidRestrictedOnMeteredNetworks(int uid) {
4704 final int uidRules;
4705 final boolean isBackgroundRestricted;
4706 synchronized (mUidRulesFirstLock) {
4707 uidRules = mUidRules.get(uid, RULE_ALLOW_ALL);
4708 isBackgroundRestricted = mRestrictBackground;
4709 }
4710 return isBackgroundRestricted
4711 && !hasRule(uidRules, RULE_ALLOW_METERED)
4712 && !hasRule(uidRules, RULE_TEMPORARY_ALLOW_METERED);
4713 }
4714
4715 /**
4716 * @return true if networking is blocked on the given interface for the given uid according
4717 * to current networking policies.
4718 */
4719 @Override
4720 public boolean isUidNetworkingBlocked(int uid, String ifname) {
Makoto Onuki49392d32018-04-11 13:51:02 -07004721 final long startTime = mStatLogger.getTime();
4722
Hugo Benichi938ab4f2017-02-11 17:04:43 +09004723 final boolean isNetworkMetered;
Sudheer Shankab8f23162017-08-04 13:30:10 -07004724 synchronized (mNetworkPoliciesSecondLock) {
4725 isNetworkMetered = mMeteredIfaces.contains(ifname);
Hugo Benichi938ab4f2017-02-11 17:04:43 +09004726 }
Makoto Onuki49392d32018-04-11 13:51:02 -07004727 final boolean ret = isUidNetworkingBlockedInternal(uid, isNetworkMetered);
4728
4729 mStatLogger.logDurationStat(Stats.IS_UID_NETWORKING_BLOCKED, startTime);
4730
4731 return ret;
Hugo Benichi938ab4f2017-02-11 17:04:43 +09004732 }
Sudheer Shankaf34f3ec2017-08-03 11:02:56 -07004733
4734 @Override
4735 public void onTempPowerSaveWhitelistChange(int appId, boolean added) {
4736 synchronized (mUidRulesFirstLock) {
Sudheer Shanka352dc572017-09-22 17:09:38 -07004737 mLogger.tempPowerSaveWlChanged(appId, added);
Sudheer Shankaf34f3ec2017-08-03 11:02:56 -07004738 if (added) {
4739 mPowerSaveTempWhitelistAppIds.put(appId, true);
4740 } else {
4741 mPowerSaveTempWhitelistAppIds.delete(appId);
4742 }
4743 updateRulesForTempWhitelistChangeUL(appId);
4744 }
4745 }
Jeff Sharkey9252b342018-01-19 07:58:35 +09004746
4747 @Override
4748 public SubscriptionPlan getSubscriptionPlan(Network network) {
4749 synchronized (mNetworkPoliciesSecondLock) {
Jeff Sharkey2e471452018-01-19 18:02:47 +09004750 final int subId = getSubIdLocked(network);
4751 return getPrimarySubscriptionPlanLocked(subId);
Jeff Sharkey9252b342018-01-19 07:58:35 +09004752 }
4753 }
4754
4755 @Override
4756 public long getSubscriptionOpportunisticQuota(Network network, int quotaType) {
Jeff Sharkey36b414b2018-03-30 11:00:03 -06004757 final long quotaBytes;
Jeff Sharkey9252b342018-01-19 07:58:35 +09004758 synchronized (mNetworkPoliciesSecondLock) {
Jeff Sharkey36b414b2018-03-30 11:00:03 -06004759 quotaBytes = mSubscriptionOpportunisticQuota.get(getSubIdLocked(network),
Remi NGUYEN VAN5a89f942018-03-30 21:17:42 +09004760 OPPORTUNISTIC_QUOTA_UNKNOWN);
Jeff Sharkey9252b342018-01-19 07:58:35 +09004761 }
Jeff Sharkey36b414b2018-03-30 11:00:03 -06004762 if (quotaBytes == OPPORTUNISTIC_QUOTA_UNKNOWN) {
4763 return OPPORTUNISTIC_QUOTA_UNKNOWN;
4764 }
4765
4766 if (quotaType == QUOTA_TYPE_JOBS) {
4767 return (long) (quotaBytes * Settings.Global.getFloat(mContext.getContentResolver(),
4768 NETPOLICY_QUOTA_FRAC_JOBS, QUOTA_FRAC_JOBS_DEFAULT));
4769 } else if (quotaType == QUOTA_TYPE_MULTIPATH) {
4770 return (long) (quotaBytes * Settings.Global.getFloat(mContext.getContentResolver(),
4771 NETPOLICY_QUOTA_FRAC_MULTIPATH, QUOTA_FRAC_MULTIPATH_DEFAULT));
4772 } else {
4773 return OPPORTUNISTIC_QUOTA_UNKNOWN;
4774 }
Jeff Sharkey9252b342018-01-19 07:58:35 +09004775 }
Sudheer Shankac53c47f2018-01-16 12:01:00 -08004776
4777 @Override
4778 public void onAdminDataAvailable() {
4779 mAdminDataAvailableLatch.countDown();
4780 }
Sudheer Shanka04d61ae2018-01-17 12:16:57 -08004781
4782 @Override
4783 public void setMeteredRestrictedPackages(Set<String> packageNames, int userId) {
4784 setMeteredRestrictedPackagesInternal(packageNames, userId);
4785 }
4786
4787 @Override
4788 public void setMeteredRestrictedPackagesAsync(Set<String> packageNames, int userId) {
4789 mHandler.obtainMessage(MSG_METERED_RESTRICTED_PACKAGES_CHANGED,
4790 userId, 0, packageNames).sendToTarget();
4791 }
4792 }
4793
4794 private void setMeteredRestrictedPackagesInternal(Set<String> packageNames, int userId) {
4795 synchronized (mUidRulesFirstLock) {
4796 final Set<Integer> newRestrictedUids = new ArraySet<>();
4797 for (String packageName : packageNames) {
4798 final int uid = getUidForPackage(packageName, userId);
4799 if (uid >= 0) {
4800 newRestrictedUids.add(uid);
4801 }
4802 }
4803 final Set<Integer> oldRestrictedUids = mMeteredRestrictedUids.get(userId);
4804 mMeteredRestrictedUids.put(userId, newRestrictedUids);
4805 handleRestrictedPackagesChangeUL(oldRestrictedUids, newRestrictedUids);
4806 mLogger.meteredRestrictedPkgsChanged(newRestrictedUids);
4807 }
4808 }
4809
4810 private int getUidForPackage(String packageName, int userId) {
4811 try {
4812 return mContext.getPackageManager().getPackageUidAsUser(packageName,
4813 PackageManager.MATCH_KNOWN_PACKAGES, userId);
4814 } catch (NameNotFoundException e) {
4815 return -1;
4816 }
Jeff Sharkey9252b342018-01-19 07:58:35 +09004817 }
4818
4819 private int parseSubId(NetworkState state) {
4820 // TODO: moved to using a legitimate NetworkSpecifier instead of string parsing
4821 int subId = INVALID_SUBSCRIPTION_ID;
4822 if (state != null && state.networkCapabilities != null
4823 && state.networkCapabilities.hasTransport(TRANSPORT_CELLULAR)) {
4824 NetworkSpecifier spec = state.networkCapabilities.getNetworkSpecifier();
4825 if (spec instanceof StringNetworkSpecifier) {
4826 try {
4827 subId = Integer.parseInt(((StringNetworkSpecifier) spec).specifier);
4828 } catch (NumberFormatException e) {
4829 }
4830 }
4831 }
4832 return subId;
4833 }
4834
Andreas Gampea36dc622018-02-05 17:19:22 -08004835 @GuardedBy("mNetworkPoliciesSecondLock")
Jeff Sharkey9252b342018-01-19 07:58:35 +09004836 private int getSubIdLocked(Network network) {
4837 return mNetIdToSubId.get(network.netId, INVALID_SUBSCRIPTION_ID);
Hugo Benichi938ab4f2017-02-11 17:04:43 +09004838 }
4839
Andreas Gampea36dc622018-02-05 17:19:22 -08004840 @GuardedBy("mNetworkPoliciesSecondLock")
Jeff Sharkey2e471452018-01-19 18:02:47 +09004841 private SubscriptionPlan getPrimarySubscriptionPlanLocked(int subId) {
4842 final SubscriptionPlan[] plans = mSubscriptionPlans.get(subId);
4843 return ArrayUtils.isEmpty(plans) ? null : plans[0];
4844 }
4845
Sudheer Shankac53c47f2018-01-16 12:01:00 -08004846 /**
4847 * This will only ever be called once - during device boot.
4848 */
4849 private void waitForAdminData() {
4850 if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN)) {
4851 ConcurrentUtils.waitForCountDownNoInterrupt(mAdminDataAvailableLatch,
4852 WAIT_FOR_ADMIN_DATA_TIMEOUT_MS, "Wait for admin data");
4853 }
4854 }
4855
Sudheer Shanka04d61ae2018-01-17 12:16:57 -08004856 private void handleRestrictedPackagesChangeUL(Set<Integer> oldRestrictedUids,
4857 Set<Integer> newRestrictedUids) {
4858 if (oldRestrictedUids == null) {
4859 for (int uid : newRestrictedUids) {
4860 updateRulesForDataUsageRestrictionsUL(uid);
4861 }
4862 return;
4863 }
4864 for (int uid : oldRestrictedUids) {
4865 if (!newRestrictedUids.contains(uid)) {
4866 updateRulesForDataUsageRestrictionsUL(uid);
4867 }
4868 }
4869 for (int uid : newRestrictedUids) {
4870 if (!oldRestrictedUids.contains(uid)) {
4871 updateRulesForDataUsageRestrictionsUL(uid);
4872 }
4873 }
4874 }
4875
4876 private boolean isRestrictedByAdminUL(int uid) {
4877 final Set<Integer> restrictedUids = mMeteredRestrictedUids.get(
4878 UserHandle.getUserId(uid));
4879 return restrictedUids != null && restrictedUids.contains(uid);
4880 }
4881
Hugo Benichi938ab4f2017-02-11 17:04:43 +09004882 private static boolean hasRule(int uidRules, int rule) {
4883 return (uidRules & rule) != 0;
4884 }
4885
Jeff Sharkey2e471452018-01-19 18:02:47 +09004886 private static @NonNull NetworkState[] defeatNullable(@Nullable NetworkState[] val) {
4887 return (val != null) ? val : new NetworkState[0];
4888 }
4889
Chris Wren193ae6b2017-03-31 15:17:11 -04004890 private class NotificationId {
4891 private final String mTag;
4892 private final int mId;
4893
4894 NotificationId(NetworkPolicy policy, int type) {
4895 mTag = buildNotificationTag(policy, type);
4896 mId = type;
4897 }
4898
4899 @Override
4900 public boolean equals(Object o) {
4901 if (this == o) return true;
4902 if (!(o instanceof NotificationId)) return false;
4903 NotificationId that = (NotificationId) o;
4904 return Objects.equals(mTag, that.mTag);
4905 }
4906
4907 @Override
4908 public int hashCode() {
4909 return Objects.hash(mTag);
4910 }
4911
4912 /**
4913 * Build unique tag that identifies an active {@link NetworkPolicy}
4914 * notification of a specific type, like {@link #TYPE_LIMIT}.
4915 */
4916 private String buildNotificationTag(NetworkPolicy policy, int type) {
4917 return TAG + ":" + policy.template.hashCode() + ":" + type;
4918 }
4919
4920 public String getTag() {
4921 return mTag;
4922 }
4923
4924 public int getId() {
4925 return mId;
4926 }
4927 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07004928}