1/*
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
19import static android.Manifest.permission.ACCESS_NETWORK_STATE;
20import static android.Manifest.permission.CONNECTIVITY_INTERNAL;
21import static android.Manifest.permission.DUMP;
22import static android.Manifest.permission.MANAGE_NETWORK_POLICY;
23import static android.Manifest.permission.READ_NETWORK_USAGE_HISTORY;
24import static android.Manifest.permission.READ_PHONE_STATE;
25import static android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE;
26import static android.content.Intent.ACTION_PACKAGE_ADDED;
27import static android.content.Intent.ACTION_UID_REMOVED;
28import static android.content.Intent.ACTION_USER_ADDED;
29import static android.content.Intent.ACTION_USER_REMOVED;
30import static android.content.Intent.EXTRA_UID;
31import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
32import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED;
33import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED;
34import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELISTED;
35import static android.net.ConnectivityManager.TYPE_MOBILE;
36import static android.net.ConnectivityManager.TYPE_WIMAX;
37import static android.net.ConnectivityManager.isNetworkTypeMobile;
38import static android.net.NetworkPolicy.CYCLE_NONE;
39import static android.net.NetworkPolicy.LIMIT_DISABLED;
40import static android.net.NetworkPolicy.SNOOZE_NEVER;
41import static android.net.NetworkPolicy.WARNING_DISABLED;
42import static android.net.NetworkPolicyManager.EXTRA_NETWORK_TEMPLATE;
43import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_DOZABLE;
44import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_POWERSAVE;
45import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_STANDBY;
46import static android.net.NetworkPolicyManager.FIREWALL_RULE_ALLOW;
47import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT;
48import static android.net.NetworkPolicyManager.FIREWALL_RULE_DENY;
49import static android.net.NetworkPolicyManager.POLICY_ALLOW_METERED_BACKGROUND;
50import static android.net.NetworkPolicyManager.POLICY_NONE;
51import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND;
52import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL;
53import static android.net.NetworkPolicyManager.RULE_ALLOW_METERED;
54import static android.net.NetworkPolicyManager.MASK_METERED_NETWORKS;
55import static android.net.NetworkPolicyManager.MASK_ALL_NETWORKS;
56import static android.net.NetworkPolicyManager.RULE_NONE;
57import static android.net.NetworkPolicyManager.RULE_REJECT_ALL;
58import static android.net.NetworkPolicyManager.RULE_REJECT_METERED;
59import static android.net.NetworkPolicyManager.RULE_TEMPORARY_ALLOW_METERED;
60import static android.net.NetworkPolicyManager.computeLastCycleBoundary;
61import static android.net.NetworkPolicyManager.isProcStateAllowedWhileIdleOrPowerSaveMode;
62import static android.net.NetworkPolicyManager.isProcStateAllowedWhileOnRestrictBackground;
63import static android.net.NetworkPolicyManager.uidPoliciesToString;
64import static android.net.NetworkPolicyManager.uidRulesToString;
65import static android.net.NetworkTemplate.MATCH_MOBILE_3G_LOWER;
66import static android.net.NetworkTemplate.MATCH_MOBILE_4G;
67import static android.net.NetworkTemplate.MATCH_MOBILE_ALL;
68import static android.net.NetworkTemplate.MATCH_WIFI;
69import static android.net.NetworkTemplate.buildTemplateMobileAll;
70import static android.net.TrafficStats.MB_IN_BYTES;
71import static android.net.wifi.WifiManager.CHANGE_REASON_ADDED;
72import static android.net.wifi.WifiManager.CHANGE_REASON_REMOVED;
73import static android.net.wifi.WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION;
74import static android.net.wifi.WifiManager.EXTRA_CHANGE_REASON;
75import static android.net.wifi.WifiManager.EXTRA_NETWORK_INFO;
76import static android.net.wifi.WifiManager.EXTRA_WIFI_CONFIGURATION;
77import static android.net.wifi.WifiManager.EXTRA_WIFI_INFO;
78import static android.telephony.CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED;
79import static android.telephony.CarrierConfigManager.DATA_CYCLE_USE_PLATFORM_DEFAULT;
80import static android.telephony.CarrierConfigManager.DATA_CYCLE_THRESHOLD_DISABLED;
81import static android.text.format.DateUtils.DAY_IN_MILLIS;
82
83import static com.android.internal.util.ArrayUtils.appendInt;
84import static com.android.internal.util.Preconditions.checkNotNull;
85import static com.android.internal.util.XmlUtils.readBooleanAttribute;
86import static com.android.internal.util.XmlUtils.readIntAttribute;
87import static com.android.internal.util.XmlUtils.readLongAttribute;
88import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
89import static com.android.internal.util.XmlUtils.writeIntAttribute;
90import static com.android.internal.util.XmlUtils.writeLongAttribute;
91import static com.android.server.NetworkManagementService.LIMIT_GLOBAL_ALERT;
92import static com.android.server.net.NetworkStatsService.ACTION_NETWORK_STATS_UPDATED;
93
94import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
95import static org.xmlpull.v1.XmlPullParser.END_TAG;
96import static org.xmlpull.v1.XmlPullParser.START_TAG;
97
98import android.Manifest;
99import android.annotation.IntDef;
100import android.annotation.Nullable;
101import android.app.ActivityManager;
102import android.app.ActivityManagerInternal;
103import android.app.AppGlobals;
104import android.app.AppOpsManager;
105import android.app.IActivityManager;
106import android.app.INotificationManager;
107import android.app.IUidObserver;
108import android.app.Notification;
109import android.app.PendingIntent;
110import android.app.usage.UsageStatsManagerInternal;
111import android.content.BroadcastReceiver;
112import android.content.ComponentName;
113import android.content.Context;
114import android.content.Intent;
115import android.content.IntentFilter;
116import android.content.pm.ApplicationInfo;
117import android.content.pm.IPackageManager;
118import android.content.pm.PackageManager;
119import android.content.pm.PackageManager.NameNotFoundException;
120import android.content.pm.UserInfo;
121import android.content.res.Resources;
122import android.net.ConnectivityManager;
123import android.net.IConnectivityManager;
124import android.net.INetworkManagementEventObserver;
125import android.net.INetworkPolicyListener;
126import android.net.INetworkPolicyManager;
127import android.net.INetworkStatsService;
128import android.net.LinkProperties;
129import android.net.NetworkIdentity;
130import android.net.NetworkInfo;
131import android.net.NetworkPolicy;
132import android.net.NetworkQuotaInfo;
133import android.net.NetworkState;
134import android.net.NetworkTemplate;
135import android.net.wifi.WifiConfiguration;
136import android.net.wifi.WifiInfo;
137import android.net.wifi.WifiManager;
138import android.os.PowerSaveState;
139import android.os.Binder;
140import android.os.Environment;
141import android.os.Handler;
142import android.os.HandlerThread;
143import android.os.IDeviceIdleController;
144import android.os.INetworkManagementService;
145import android.os.Message;
146import android.os.MessageQueue.IdleHandler;
147import android.os.PersistableBundle;
148import android.os.PowerManager;
149import android.os.PowerManagerInternal;
150import android.os.Process;
151import android.os.RemoteCallbackList;
152import android.os.RemoteException;
153import android.os.ResultReceiver;
154import android.os.ServiceManager;
155import android.os.ShellCallback;
156import android.os.Trace;
157import android.os.UserHandle;
158import android.os.UserManager;
159import android.provider.Settings;
160import android.telephony.CarrierConfigManager;
161import android.telephony.SubscriptionManager;
162import android.telephony.TelephonyManager;
163import android.text.TextUtils;
164import android.text.format.Formatter;
165import android.text.format.Time;
166import android.util.ArrayMap;
167import android.util.ArraySet;
168import android.util.AtomicFile;
169import android.util.Log;
170import android.util.NtpTrustedTime;
171import android.util.Pair;
172import android.util.Slog;
173import android.util.SparseBooleanArray;
174import android.util.SparseIntArray;
175import android.util.TrustedTime;
176import android.util.Xml;
177
178import com.android.internal.R;
179import com.android.internal.annotations.GuardedBy;
180import com.android.internal.annotations.VisibleForTesting;
181import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
182import com.android.internal.notification.SystemNotificationChannels;
183import com.android.internal.telephony.PhoneConstants;
184import com.android.internal.util.ArrayUtils;
185import com.android.internal.util.DumpUtils;
186import com.android.internal.util.FastXmlSerializer;
187import com.android.internal.util.IndentingPrintWriter;
188import com.android.server.DeviceIdleController;
189import com.android.server.EventLogTags;
190import com.android.server.LocalServices;
191import com.android.server.ServiceThread;
192import com.android.server.SystemConfig;
193
194import com.android.server.power.BatterySaverPolicy.ServiceType;
195import libcore.io.IoUtils;
196
197import com.google.android.collect.Lists;
198
199import org.xmlpull.v1.XmlPullParser;
200import org.xmlpull.v1.XmlPullParserException;
201import org.xmlpull.v1.XmlSerializer;
202
203import java.io.File;
204import java.io.FileDescriptor;
205import java.io.FileInputStream;
206import java.io.FileNotFoundException;
207import java.io.FileOutputStream;
208import java.io.IOException;
209import java.io.PrintWriter;
210import java.lang.annotation.Retention;
211import java.lang.annotation.RetentionPolicy;
212import java.nio.charset.StandardCharsets;
213import java.util.ArrayList;
214import java.util.Arrays;
215import java.util.List;
216import java.util.Calendar;
217import java.util.Objects;
218import java.util.concurrent.CountDownLatch;
219import java.util.concurrent.TimeUnit;
220
221/**
222 * Service that maintains low-level network policy rules, using
223 * {@link NetworkStatsService} statistics to drive those rules.
224 * <p>
225 * Derives active rules by combining a given policy with other system status,
226 * and delivers to listeners, such as {@link ConnectivityManager}, for
227 * enforcement.
228 *
229 * <p>
230 * This class uses 2-3 locks to synchronize state:
231 * <ul>
232 * <li>{@code mUidRulesFirstLock}: used to guard state related to individual UIDs (such as firewall
233 * rules).
234 * <li>{@code mNetworkPoliciesSecondLock}: used to guard state related to network interfaces (such
235 * as network policies).
236 * <li>{@code allLocks}: not a "real" lock, but an indication (through @GuardedBy) that all locks
237 * must be held.
238 * </ul>
239 *
240 * <p>
241 * As such, methods that require synchronization have the following prefixes:
242 * <ul>
243 * <li>{@code UL()}: require the "UID" lock ({@code mUidRulesFirstLock}).
244 * <li>{@code NL()}: require the "Network" lock ({@code mNetworkPoliciesSecondLock}).
245 * <li>{@code AL()}: require all locks, which must be obtained in order ({@code mUidRulesFirstLock}
246 * first, then {@code mNetworkPoliciesSecondLock}, then {@code mYetAnotherGuardThirdLock}, etc..
247 * </ul>
248 */
249public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
250    static final String TAG = "NetworkPolicy";
251    private static final boolean LOGD = false;
252    private static final boolean LOGV = false;
253
254    private static final int VERSION_INIT = 1;
255    private static final int VERSION_ADDED_SNOOZE = 2;
256    private static final int VERSION_ADDED_RESTRICT_BACKGROUND = 3;
257    private static final int VERSION_ADDED_METERED = 4;
258    private static final int VERSION_SPLIT_SNOOZE = 5;
259    private static final int VERSION_ADDED_TIMEZONE = 6;
260    private static final int VERSION_ADDED_INFERRED = 7;
261    private static final int VERSION_SWITCH_APP_ID = 8;
262    private static final int VERSION_ADDED_NETWORK_ID = 9;
263    private static final int VERSION_SWITCH_UID = 10;
264    private static final int VERSION_LATEST = VERSION_SWITCH_UID;
265
266    /**
267     * Max items written to {@link #ProcStateSeqHistory}.
268     */
269    @VisibleForTesting
270    public static final int MAX_PROC_STATE_SEQ_HISTORY =
271            ActivityManager.isLowRamDeviceStatic() ? 50 : 200;
272
273    @VisibleForTesting
274    public static final int TYPE_WARNING = SystemMessage.NOTE_NET_WARNING;
275    @VisibleForTesting
276    public static final int TYPE_LIMIT = SystemMessage.NOTE_NET_LIMIT;
277    @VisibleForTesting
278    public static final int TYPE_LIMIT_SNOOZED = SystemMessage.NOTE_NET_LIMIT_SNOOZED;
279
280    private static final String TAG_POLICY_LIST = "policy-list";
281    private static final String TAG_NETWORK_POLICY = "network-policy";
282    private static final String TAG_UID_POLICY = "uid-policy";
283    private static final String TAG_APP_POLICY = "app-policy";
284    private static final String TAG_WHITELIST = "whitelist";
285    private static final String TAG_RESTRICT_BACKGROUND = "restrict-background";
286    private static final String TAG_REVOKED_RESTRICT_BACKGROUND = "revoked-restrict-background";
287
288    private static final String ATTR_VERSION = "version";
289    private static final String ATTR_RESTRICT_BACKGROUND = "restrictBackground";
290    private static final String ATTR_NETWORK_TEMPLATE = "networkTemplate";
291    private static final String ATTR_SUBSCRIBER_ID = "subscriberId";
292    private static final String ATTR_NETWORK_ID = "networkId";
293    private static final String ATTR_CYCLE_DAY = "cycleDay";
294    private static final String ATTR_CYCLE_TIMEZONE = "cycleTimezone";
295    private static final String ATTR_WARNING_BYTES = "warningBytes";
296    private static final String ATTR_LIMIT_BYTES = "limitBytes";
297    private static final String ATTR_LAST_SNOOZE = "lastSnooze";
298    private static final String ATTR_LAST_WARNING_SNOOZE = "lastWarningSnooze";
299    private static final String ATTR_LAST_LIMIT_SNOOZE = "lastLimitSnooze";
300    private static final String ATTR_METERED = "metered";
301    private static final String ATTR_INFERRED = "inferred";
302    private static final String ATTR_UID = "uid";
303    private static final String ATTR_APP_ID = "appId";
304    private static final String ATTR_POLICY = "policy";
305
306    private static final String ACTION_ALLOW_BACKGROUND =
307            "com.android.server.net.action.ALLOW_BACKGROUND";
308    private static final String ACTION_SNOOZE_WARNING =
309            "com.android.server.net.action.SNOOZE_WARNING";
310
311    private static final long TIME_CACHE_MAX_AGE = DAY_IN_MILLIS;
312
313    private static final int MSG_RULES_CHANGED = 1;
314    private static final int MSG_METERED_IFACES_CHANGED = 2;
315    private static final int MSG_LIMIT_REACHED = 5;
316    private static final int MSG_RESTRICT_BACKGROUND_CHANGED = 6;
317    private static final int MSG_ADVISE_PERSIST_THRESHOLD = 7;
318    private static final int MSG_UPDATE_INTERFACE_QUOTA = 10;
319    private static final int MSG_REMOVE_INTERFACE_QUOTA = 11;
320    private static final int MSG_POLICIES_CHANGED = 13;
321    private static final int MSG_SET_FIREWALL_RULES = 14;
322    private static final int MSG_RESET_FIREWALL_RULES_BY_UID = 15;
323
324    private static final int UID_MSG_STATE_CHANGED = 100;
325    private static final int UID_MSG_GONE = 101;
326
327    private final Context mContext;
328    private final IActivityManager mActivityManager;
329    private final INetworkStatsService mNetworkStats;
330    private final INetworkManagementService mNetworkManager;
331    private UsageStatsManagerInternal mUsageStats;
332    private final TrustedTime mTime;
333    private final UserManager mUserManager;
334    private final CarrierConfigManager mCarrierConfigManager;
335
336    private IConnectivityManager mConnManager;
337    private INotificationManager mNotifManager;
338    private PowerManagerInternal mPowerManagerInternal;
339    private IDeviceIdleController mDeviceIdleController;
340    @GuardedBy("mUidRulesFirstLock")
341    private PowerSaveState mRestrictBackgroundPowerState;
342
343    // Store the status of restrict background before turning on battery saver.
344    // Used to restore mRestrictBackground when battery saver is turned off.
345    private boolean mRestrictBackgroundBeforeBsm;
346
347    // See main javadoc for instructions on how to use these locks.
348    final Object mUidRulesFirstLock = new Object();
349    final Object mNetworkPoliciesSecondLock = new Object();
350
351    @GuardedBy("allLocks") volatile boolean mSystemReady;
352
353    @GuardedBy("mUidRulesFirstLock") volatile boolean mRestrictBackground;
354    @GuardedBy("mUidRulesFirstLock") volatile boolean mRestrictPower;
355    @GuardedBy("mUidRulesFirstLock") volatile boolean mDeviceIdleMode;
356    // Store whether user flipped restrict background in battery saver mode
357    @GuardedBy("mUidRulesFirstLock") volatile boolean mRestrictBackgroundChangedInBsm;
358
359    private final boolean mSuppressDefaultPolicy;
360
361    /** Defined network policies. */
362    final ArrayMap<NetworkTemplate, NetworkPolicy> mNetworkPolicy = new ArrayMap<>();
363    /** Currently active network rules for ifaces. */
364    final ArrayMap<NetworkPolicy, String[]> mNetworkRules = new ArrayMap<>();
365
366    /** Defined UID policies. */
367    @GuardedBy("mUidRulesFirstLock") final SparseIntArray mUidPolicy = new SparseIntArray();
368    /** Currently derived rules for each UID. */
369    @GuardedBy("mUidRulesFirstLock") final SparseIntArray mUidRules = new SparseIntArray();
370
371    @GuardedBy("mUidRulesFirstLock")
372    final SparseIntArray mUidFirewallStandbyRules = new SparseIntArray();
373    @GuardedBy("mUidRulesFirstLock")
374    final SparseIntArray mUidFirewallDozableRules = new SparseIntArray();
375    @GuardedBy("mUidRulesFirstLock")
376    final SparseIntArray mUidFirewallPowerSaveRules = new SparseIntArray();
377
378    /** Set of states for the child firewall chains. True if the chain is active. */
379    @GuardedBy("mUidRulesFirstLock")
380    final SparseBooleanArray mFirewallChainStates = new SparseBooleanArray();
381
382    /**
383     * UIDs that have been white-listed to always be able to have network access
384     * in power save mode, except device idle (doze) still applies.
385     * TODO: An int array might be sufficient
386     */
387    @GuardedBy("mUidRulesFirstLock")
388    private final SparseBooleanArray mPowerSaveWhitelistExceptIdleAppIds = new SparseBooleanArray();
389
390    /**
391     * UIDs that have been white-listed to always be able to have network access
392     * in power save mode.
393     * TODO: An int array might be sufficient
394     */
395    @GuardedBy("mUidRulesFirstLock")
396    private final SparseBooleanArray mPowerSaveWhitelistAppIds = new SparseBooleanArray();
397
398    @GuardedBy("mUidRulesFirstLock")
399    private final SparseBooleanArray mPowerSaveTempWhitelistAppIds = new SparseBooleanArray();
400
401    /**
402     * UIDs that have been initially white-listed by system to avoid restricted background.
403     */
404    @GuardedBy("mUidRulesFirstLock")
405    private final SparseBooleanArray mDefaultRestrictBackgroundWhitelistUids =
406            new SparseBooleanArray();
407
408    /**
409     * UIDs that have been initially white-listed by system to avoid restricted background,
410     * but later revoked by user.
411     */
412    @GuardedBy("mUidRulesFirstLock")
413    private final SparseBooleanArray mRestrictBackgroundWhitelistRevokedUids =
414            new SparseBooleanArray();
415
416    /** Set of ifaces that are metered. */
417    @GuardedBy("mNetworkPoliciesSecondLock")
418    private ArraySet<String> mMeteredIfaces = new ArraySet<>();
419    /** Set of over-limit templates that have been notified. */
420    @GuardedBy("mNetworkPoliciesSecondLock")
421    private final ArraySet<NetworkTemplate> mOverLimitNotified = new ArraySet<>();
422
423    /** Set of currently active {@link Notification} tags. */
424    @GuardedBy("mNetworkPoliciesSecondLock")
425    private final ArraySet<NotificationId> mActiveNotifs = new ArraySet<>();
426
427    /** Foreground at UID granularity. */
428    @GuardedBy("mUidRulesFirstLock")
429    final SparseIntArray mUidState = new SparseIntArray();
430
431    private final RemoteCallbackList<INetworkPolicyListener>
432            mListeners = new RemoteCallbackList<>();
433
434    final Handler mHandler;
435    @VisibleForTesting
436    public final Handler mUidEventHandler;
437
438    private final ServiceThread mUidEventThread;
439
440    @GuardedBy("allLocks")
441    private final AtomicFile mPolicyFile;
442
443    private final AppOpsManager mAppOps;
444
445    private final IPackageManager mIPm;
446
447    private ActivityManagerInternal mActivityManagerInternal;
448
449    /**
450     * This is used for debugging purposes. Whenever the IUidObserver.onUidStateChanged is called,
451     * the uid and procStateSeq will be written to this and will be printed as part of dump.
452     */
453    @VisibleForTesting
454    public ProcStateSeqHistory mObservedHistory
455            = new ProcStateSeqHistory(MAX_PROC_STATE_SEQ_HISTORY);
456
457    // TODO: keep whitelist of system-critical services that should never have
458    // rules enforced, such as system, phone, and radio UIDs.
459
460    // TODO: migrate notifications to SystemUI
461
462    public NetworkPolicyManagerService(Context context, IActivityManager activityManager,
463            INetworkStatsService networkStats, INetworkManagementService networkManagement) {
464        this(context, activityManager, networkStats, networkManagement,
465                AppGlobals.getPackageManager(), NtpTrustedTime.getInstance(context), getSystemDir(),
466                false);
467    }
468
469    private static File getSystemDir() {
470        return new File(Environment.getDataDirectory(), "system");
471    }
472
473    public NetworkPolicyManagerService(Context context, IActivityManager activityManager,
474            INetworkStatsService networkStats, INetworkManagementService networkManagement,
475            IPackageManager pm, TrustedTime time, File systemDir, boolean suppressDefaultPolicy) {
476        mContext = checkNotNull(context, "missing context");
477        mActivityManager = checkNotNull(activityManager, "missing activityManager");
478        mNetworkStats = checkNotNull(networkStats, "missing networkStats");
479        mNetworkManager = checkNotNull(networkManagement, "missing networkManagement");
480        mDeviceIdleController = IDeviceIdleController.Stub.asInterface(ServiceManager.getService(
481                Context.DEVICE_IDLE_CONTROLLER));
482        mTime = checkNotNull(time, "missing TrustedTime");
483        mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
484        mCarrierConfigManager = mContext.getSystemService(CarrierConfigManager.class);
485        mIPm = pm;
486
487        HandlerThread thread = new HandlerThread(TAG);
488        thread.start();
489        mHandler = new Handler(thread.getLooper(), mHandlerCallback);
490
491        // We create another thread for the UID events, which are more time-critical.
492        mUidEventThread = new ServiceThread(TAG + ".uid", Process.THREAD_PRIORITY_FOREGROUND,
493                /*allowIo=*/ false);
494        mUidEventThread.start();
495        mUidEventHandler = new Handler(mUidEventThread.getLooper(), mUidEventHandlerCallback);
496
497        mSuppressDefaultPolicy = suppressDefaultPolicy;
498
499        mPolicyFile = new AtomicFile(new File(systemDir, "netpolicy.xml"));
500
501        mAppOps = context.getSystemService(AppOpsManager.class);
502
503        // Expose private service for system components to use.
504        LocalServices.addService(NetworkPolicyManagerInternal.class,
505                new NetworkPolicyManagerInternalImpl());
506    }
507
508    public void bindConnectivityManager(IConnectivityManager connManager) {
509        mConnManager = checkNotNull(connManager, "missing IConnectivityManager");
510    }
511
512    public void bindNotificationManager(INotificationManager notifManager) {
513        mNotifManager = checkNotNull(notifManager, "missing INotificationManager");
514    }
515
516    void updatePowerSaveWhitelistUL() {
517        try {
518            int[] whitelist = mDeviceIdleController.getAppIdWhitelistExceptIdle();
519            mPowerSaveWhitelistExceptIdleAppIds.clear();
520            if (whitelist != null) {
521                for (int uid : whitelist) {
522                    mPowerSaveWhitelistExceptIdleAppIds.put(uid, true);
523                }
524            }
525            whitelist = mDeviceIdleController.getAppIdWhitelist();
526            mPowerSaveWhitelistAppIds.clear();
527            if (whitelist != null) {
528                for (int uid : whitelist) {
529                    mPowerSaveWhitelistAppIds.put(uid, true);
530                }
531            }
532        } catch (RemoteException e) {
533        }
534    }
535
536    /**
537     * Whitelists pre-defined apps for restrict background, but only if the user didn't already
538     * revoke the whitelist.
539     *
540     * @return whether any uid has been whitelisted.
541     */
542    boolean addDefaultRestrictBackgroundWhitelistUidsUL() {
543        final List<UserInfo> users = mUserManager.getUsers();
544        final int numberUsers = users.size();
545
546        boolean changed = false;
547        for (int i = 0; i < numberUsers; i++) {
548            final UserInfo user = users.get(i);
549            changed = addDefaultRestrictBackgroundWhitelistUidsUL(user.id) || changed;
550        }
551        return changed;
552    }
553
554    private boolean addDefaultRestrictBackgroundWhitelistUidsUL(int userId) {
555        final SystemConfig sysConfig = SystemConfig.getInstance();
556        final PackageManager pm = mContext.getPackageManager();
557        final ArraySet<String> allowDataUsage = sysConfig.getAllowInDataUsageSave();
558        boolean changed = false;
559        for (int i = 0; i < allowDataUsage.size(); i++) {
560            final String pkg = allowDataUsage.valueAt(i);
561            if (LOGD)
562                Slog.d(TAG, "checking restricted background whitelisting for package " + pkg
563                        + " and user " + userId);
564            final ApplicationInfo app;
565            try {
566                app = pm.getApplicationInfoAsUser(pkg, PackageManager.MATCH_SYSTEM_ONLY, userId);
567            } catch (PackageManager.NameNotFoundException e) {
568                if (LOGD) Slog.d(TAG, "No ApplicationInfo for package " + pkg);
569                // Ignore it - some apps on allow-in-data-usage-save are optional.
570                continue;
571            }
572            if (!app.isPrivilegedApp()) {
573                Slog.e(TAG, "addDefaultRestrictBackgroundWhitelistUidsUL(): "
574                        + "skipping non-privileged app  " + pkg);
575                continue;
576            }
577            final int uid = UserHandle.getUid(userId, app.uid);
578            mDefaultRestrictBackgroundWhitelistUids.append(uid, true);
579            if (LOGD)
580                Slog.d(TAG, "Adding uid " + uid + " (user " + userId + ") to default restricted "
581                        + "background whitelist. Revoked status: "
582                        + mRestrictBackgroundWhitelistRevokedUids.get(uid));
583            if (!mRestrictBackgroundWhitelistRevokedUids.get(uid)) {
584                if (LOGD)
585                    Slog.d(TAG, "adding default package " + pkg + " (uid " + uid + " for user "
586                            + userId + ") to restrict background whitelist");
587                setUidPolicyUncheckedUL(uid, POLICY_ALLOW_METERED_BACKGROUND, false);
588                changed = true;
589            }
590        }
591        return changed;
592    }
593
594    void updatePowerSaveTempWhitelistUL() {
595        try {
596            // Clear the states of the current whitelist
597            final int N = mPowerSaveTempWhitelistAppIds.size();
598            for (int i = 0; i < N; i++) {
599                mPowerSaveTempWhitelistAppIds.setValueAt(i, false);
600            }
601            // Update the states with the new whitelist
602            final int[] whitelist = mDeviceIdleController.getAppIdTempWhitelist();
603            if (whitelist != null) {
604                for (int uid : whitelist) {
605                    mPowerSaveTempWhitelistAppIds.put(uid, true);
606                }
607            }
608        } catch (RemoteException e) {
609        }
610    }
611
612    /**
613     * Remove unnecessary entries in the temp whitelist
614     */
615    void purgePowerSaveTempWhitelistUL() {
616        final int N = mPowerSaveTempWhitelistAppIds.size();
617        for (int i = N - 1; i >= 0; i--) {
618            if (mPowerSaveTempWhitelistAppIds.valueAt(i) == false) {
619                mPowerSaveTempWhitelistAppIds.removeAt(i);
620            }
621        }
622    }
623
624    private void initService(CountDownLatch initCompleteSignal) {
625        Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "systemReady");
626        final int oldPriority = Process.getThreadPriority(Process.myTid());
627        try {
628            // Boost thread's priority during system server init
629            Process.setThreadPriority(Process.THREAD_PRIORITY_FOREGROUND);
630            if (!isBandwidthControlEnabled()) {
631                Slog.w(TAG, "bandwidth controls disabled, unable to enforce policy");
632                return;
633            }
634
635            mUsageStats = LocalServices.getService(UsageStatsManagerInternal.class);
636
637            synchronized (mUidRulesFirstLock) {
638                synchronized (mNetworkPoliciesSecondLock) {
639                    updatePowerSaveWhitelistUL();
640                    mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
641                    mPowerManagerInternal.registerLowPowerModeObserver(
642                            new PowerManagerInternal.LowPowerModeListener() {
643                                @Override
644                                public int getServiceType() {
645                                    return ServiceType.NETWORK_FIREWALL;
646                                }
647
648                                @Override
649                                public void onLowPowerModeChanged(PowerSaveState result) {
650                                    final boolean enabled = result.batterySaverEnabled;
651                                    if (LOGD) {
652                                        Slog.d(TAG, "onLowPowerModeChanged(" + enabled + ")");
653                                    }
654                                    synchronized (mUidRulesFirstLock) {
655                                        if (mRestrictPower != enabled) {
656                                            mRestrictPower = enabled;
657                                            updateRulesForRestrictPowerUL();
658                                        }
659                                    }
660                                }
661                            });
662                    mRestrictPower = mPowerManagerInternal.getLowPowerState(
663                            ServiceType.NETWORK_FIREWALL).batterySaverEnabled;
664
665                    mSystemReady = true;
666
667                    // read policy from disk
668                    readPolicyAL();
669
670                    // Update the restrictBackground if battery saver is turned on
671                    mRestrictBackgroundBeforeBsm = mRestrictBackground;
672                    mRestrictBackgroundPowerState = mPowerManagerInternal
673                            .getLowPowerState(ServiceType.DATA_SAVER);
674                    final boolean localRestrictBackground =
675                            mRestrictBackgroundPowerState.batterySaverEnabled;
676                    if (localRestrictBackground && localRestrictBackground != mRestrictBackground) {
677                        mRestrictBackground = localRestrictBackground;
678                        mHandler.obtainMessage(MSG_RESTRICT_BACKGROUND_CHANGED,
679                                mRestrictBackground ? 1 : 0, 0).sendToTarget();
680                    }
681                    mPowerManagerInternal.registerLowPowerModeObserver(
682                            new PowerManagerInternal.LowPowerModeListener() {
683                                @Override
684                                public int getServiceType() {
685                                    return ServiceType.DATA_SAVER;
686                                }
687
688                                @Override
689                                public void onLowPowerModeChanged(PowerSaveState result) {
690                                    synchronized (mUidRulesFirstLock) {
691                                        updateRestrictBackgroundByLowPowerModeUL(result);
692                                    }
693                                }
694                            });
695
696                    if (addDefaultRestrictBackgroundWhitelistUidsUL()) {
697                        writePolicyAL();
698                    }
699
700                    setRestrictBackgroundUL(mRestrictBackground);
701                    updateRulesForGlobalChangeAL(false);
702                    updateNotificationsNL();
703                }
704            }
705
706            mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
707            try {
708                mActivityManager.registerUidObserver(mUidObserver,
709                        ActivityManager.UID_OBSERVER_PROCSTATE|ActivityManager.UID_OBSERVER_GONE,
710                        ActivityManager.PROCESS_STATE_UNKNOWN, null);
711                mNetworkManager.registerObserver(mAlertObserver);
712            } catch (RemoteException e) {
713                // ignored; both services live in system_server
714            }
715
716            // listen for changes to power save whitelist
717            final IntentFilter whitelistFilter = new IntentFilter(
718                    PowerManager.ACTION_POWER_SAVE_WHITELIST_CHANGED);
719            mContext.registerReceiver(mPowerSaveWhitelistReceiver, whitelistFilter, null, mHandler);
720
721            DeviceIdleController.LocalService deviceIdleService
722                    = LocalServices.getService(DeviceIdleController.LocalService.class);
723            deviceIdleService.setNetworkPolicyTempWhitelistCallback(mTempPowerSaveChangedCallback);
724
725            // watch for network interfaces to be claimed
726            final IntentFilter connFilter = new IntentFilter(CONNECTIVITY_ACTION);
727            mContext.registerReceiver(mConnReceiver, connFilter, CONNECTIVITY_INTERNAL, mHandler);
728
729            // listen for package changes to update policy
730            final IntentFilter packageFilter = new IntentFilter();
731            packageFilter.addAction(ACTION_PACKAGE_ADDED);
732            packageFilter.addDataScheme("package");
733            mContext.registerReceiver(mPackageReceiver, packageFilter, null, mHandler);
734
735            // listen for UID changes to update policy
736            mContext.registerReceiver(
737                    mUidRemovedReceiver, new IntentFilter(ACTION_UID_REMOVED), null, mHandler);
738
739            // listen for user changes to update policy
740            final IntentFilter userFilter = new IntentFilter();
741            userFilter.addAction(ACTION_USER_ADDED);
742            userFilter.addAction(ACTION_USER_REMOVED);
743            mContext.registerReceiver(mUserReceiver, userFilter, null, mHandler);
744
745            // listen for stats update events
746            final IntentFilter statsFilter = new IntentFilter(ACTION_NETWORK_STATS_UPDATED);
747            mContext.registerReceiver(
748                    mStatsReceiver, statsFilter, READ_NETWORK_USAGE_HISTORY, mHandler);
749
750            // listen for restrict background changes from notifications
751            final IntentFilter allowFilter = new IntentFilter(ACTION_ALLOW_BACKGROUND);
752            mContext.registerReceiver(mAllowReceiver, allowFilter, MANAGE_NETWORK_POLICY, mHandler);
753
754            // listen for snooze warning from notifications
755            final IntentFilter snoozeWarningFilter = new IntentFilter(ACTION_SNOOZE_WARNING);
756            mContext.registerReceiver(mSnoozeWarningReceiver, snoozeWarningFilter,
757                    MANAGE_NETWORK_POLICY, mHandler);
758
759            // listen for configured wifi networks to be removed
760            final IntentFilter wifiConfigFilter =
761                    new IntentFilter(CONFIGURED_NETWORKS_CHANGED_ACTION);
762            mContext.registerReceiver(mWifiConfigReceiver, wifiConfigFilter, null, mHandler);
763
764            // listen for wifi state changes to catch metered hint
765            final IntentFilter wifiStateFilter = new IntentFilter(
766                    WifiManager.NETWORK_STATE_CHANGED_ACTION);
767            mContext.registerReceiver(mWifiStateReceiver, wifiStateFilter, null, mHandler);
768
769            // listen for carrier config changes to update data cycle information
770            final IntentFilter carrierConfigFilter = new IntentFilter(
771                    ACTION_CARRIER_CONFIG_CHANGED);
772            mContext.registerReceiver(mCarrierConfigReceiver, carrierConfigFilter, null, mHandler);
773
774            mUsageStats.addAppIdleStateChangeListener(new AppIdleStateChangeListener());
775            // tell systemReady() that the service has been initialized
776            initCompleteSignal.countDown();
777        } finally {
778            // Restore the default priority after init is done
779            Process.setThreadPriority(oldPriority);
780            Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
781        }
782    }
783
784    public CountDownLatch networkScoreAndNetworkManagementServiceReady() {
785        final CountDownLatch initCompleteSignal = new CountDownLatch(1);
786        mHandler.post(() -> initService(initCompleteSignal));
787        return initCompleteSignal;
788    }
789
790    public void systemReady(CountDownLatch initCompleteSignal) {
791        // wait for initService to complete
792        try {
793            if (!initCompleteSignal.await(30, TimeUnit.SECONDS)) {
794                throw new IllegalStateException("Service " + TAG +" init timeout");
795            }
796        } catch (InterruptedException e) {
797            Thread.currentThread().interrupt();
798            throw new IllegalStateException("Service " + TAG + " init interrupted", e);
799        }
800    }
801
802    final private IUidObserver mUidObserver = new IUidObserver.Stub() {
803        @Override public void onUidStateChanged(int uid, int procState,
804                long procStateSeq) throws RemoteException {
805            mUidEventHandler.obtainMessage(UID_MSG_STATE_CHANGED,
806                    uid, procState, procStateSeq).sendToTarget();
807        }
808
809        @Override public void onUidGone(int uid, boolean disabled) throws RemoteException {
810            mUidEventHandler.obtainMessage(UID_MSG_GONE, uid, 0).sendToTarget();
811        }
812
813        @Override public void onUidActive(int uid) throws RemoteException {
814        }
815
816        @Override public void onUidIdle(int uid, boolean disabled) throws RemoteException {
817        }
818    };
819
820    final private BroadcastReceiver mPowerSaveWhitelistReceiver = new BroadcastReceiver() {
821        @Override
822        public void onReceive(Context context, Intent intent) {
823            // on background handler thread, and POWER_SAVE_WHITELIST_CHANGED is protected
824            synchronized (mUidRulesFirstLock) {
825                updatePowerSaveWhitelistUL();
826                updateRulesForRestrictPowerUL();
827                updateRulesForAppIdleUL();
828            }
829        }
830    };
831
832    final private Runnable mTempPowerSaveChangedCallback = new Runnable() {
833        @Override
834        public void run() {
835            synchronized (mUidRulesFirstLock) {
836                updatePowerSaveTempWhitelistUL();
837                updateRulesForTempWhitelistChangeUL();
838                purgePowerSaveTempWhitelistUL();
839            }
840        }
841    };
842
843    final private BroadcastReceiver mPackageReceiver = new BroadcastReceiver() {
844        @Override
845        public void onReceive(Context context, Intent intent) {
846            // on background handler thread, and PACKAGE_ADDED is protected
847
848            final String action = intent.getAction();
849            final int uid = intent.getIntExtra(EXTRA_UID, -1);
850            if (uid == -1) return;
851
852            if (ACTION_PACKAGE_ADDED.equals(action)) {
853                // update rules for UID, since it might be subject to
854                // global background data policy
855                if (LOGV) Slog.v(TAG, "ACTION_PACKAGE_ADDED for uid=" + uid);
856                synchronized (mUidRulesFirstLock) {
857                    updateRestrictionRulesForUidUL(uid);
858                }
859            }
860        }
861    };
862
863    final private BroadcastReceiver mUidRemovedReceiver = new BroadcastReceiver() {
864        @Override
865        public void onReceive(Context context, Intent intent) {
866            // on background handler thread, and UID_REMOVED is protected
867
868            final int uid = intent.getIntExtra(EXTRA_UID, -1);
869            if (uid == -1) return;
870
871            // remove any policy and update rules to clean up
872            if (LOGV) Slog.v(TAG, "ACTION_UID_REMOVED for uid=" + uid);
873            synchronized (mUidRulesFirstLock) {
874                onUidDeletedUL(uid);
875                synchronized (mNetworkPoliciesSecondLock) {
876                    writePolicyAL();
877                }
878            }
879        }
880    };
881
882    final private BroadcastReceiver mUserReceiver = new BroadcastReceiver() {
883        @Override
884        public void onReceive(Context context, Intent intent) {
885            // on background handler thread, and USER_ADDED and USER_REMOVED
886            // broadcasts are protected
887
888            final String action = intent.getAction();
889            final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
890            if (userId == -1) return;
891
892            switch (action) {
893                case ACTION_USER_REMOVED:
894                case ACTION_USER_ADDED:
895                    synchronized (mUidRulesFirstLock) {
896                        // Remove any persistable state for the given user; both cleaning up after a
897                        // USER_REMOVED, and one last sanity check during USER_ADDED
898                        removeUserStateUL(userId, true);
899                        if (action == ACTION_USER_ADDED) {
900                            // Add apps that are whitelisted by default.
901                            addDefaultRestrictBackgroundWhitelistUidsUL(userId);
902                        }
903                        // Update global restrict for that user
904                        synchronized (mNetworkPoliciesSecondLock) {
905                            updateRulesForGlobalChangeAL(true);
906                        }
907                    }
908                    break;
909            }
910        }
911    };
912
913    /**
914     * Receiver that watches for {@link INetworkStatsService} updates, which we
915     * use to check against {@link NetworkPolicy#warningBytes}.
916     */
917    final private BroadcastReceiver mStatsReceiver = new BroadcastReceiver() {
918        @Override
919        public void onReceive(Context context, Intent intent) {
920            // on background handler thread, and verified
921            // READ_NETWORK_USAGE_HISTORY permission above.
922
923            maybeRefreshTrustedTime();
924            synchronized (mNetworkPoliciesSecondLock) {
925                updateNetworkEnabledNL();
926                updateNotificationsNL();
927            }
928        }
929    };
930
931    /**
932     * Receiver that watches for {@link Notification} control of
933     * {@link #mRestrictBackground}.
934     */
935    final private BroadcastReceiver mAllowReceiver = new BroadcastReceiver() {
936        @Override
937        public void onReceive(Context context, Intent intent) {
938            // on background handler thread, and verified MANAGE_NETWORK_POLICY
939            // permission above.
940
941            setRestrictBackground(false);
942        }
943    };
944
945    /**
946     * Receiver that watches for {@link Notification} control of
947     * {@link NetworkPolicy#lastWarningSnooze}.
948     */
949    final private BroadcastReceiver mSnoozeWarningReceiver = new BroadcastReceiver() {
950        @Override
951        public void onReceive(Context context, Intent intent) {
952            // on background handler thread, and verified MANAGE_NETWORK_POLICY
953            // permission above.
954
955            final NetworkTemplate template = intent.getParcelableExtra(EXTRA_NETWORK_TEMPLATE);
956            performSnooze(template, TYPE_WARNING);
957        }
958    };
959
960    /**
961     * Receiver that watches for {@link WifiConfiguration} to be changed.
962     */
963    final private BroadcastReceiver mWifiConfigReceiver = new BroadcastReceiver() {
964        @Override
965        public void onReceive(Context context, Intent intent) {
966            // on background handler thread, and verified CONNECTIVITY_INTERNAL
967            // permission above.
968
969            final int reason = intent.getIntExtra(EXTRA_CHANGE_REASON, CHANGE_REASON_ADDED);
970            if (reason == CHANGE_REASON_REMOVED) {
971                final WifiConfiguration config = intent.getParcelableExtra(
972                        EXTRA_WIFI_CONFIGURATION);
973                if (config.SSID != null) {
974                    final NetworkTemplate template = NetworkTemplate.buildTemplateWifi(config.SSID);
975                    synchronized (mUidRulesFirstLock) {
976                        synchronized (mNetworkPoliciesSecondLock) {
977                            if (mNetworkPolicy.containsKey(template)) {
978                                mNetworkPolicy.remove(template);
979                                writePolicyAL();
980                            }
981                        }
982                    }
983                }
984            }
985        }
986    };
987
988    /**
989     * Receiver that watches {@link WifiInfo} state changes to infer metered
990     * state. Ignores hints when policy is user-defined.
991     */
992    final private BroadcastReceiver mWifiStateReceiver = new BroadcastReceiver() {
993        @Override
994        public void onReceive(Context context, Intent intent) {
995            // on background handler thread, and verified CONNECTIVITY_INTERNAL
996            // permission above.
997
998            // ignore when not connected
999            final NetworkInfo netInfo = intent.getParcelableExtra(EXTRA_NETWORK_INFO);
1000            if (!netInfo.isConnected()) return;
1001
1002            final WifiInfo info = intent.getParcelableExtra(EXTRA_WIFI_INFO);
1003            final boolean meteredHint = info.getMeteredHint();
1004
1005            final NetworkTemplate template = NetworkTemplate.buildTemplateWifi(info.getSSID());
1006            synchronized (mUidRulesFirstLock) {
1007                synchronized (mNetworkPoliciesSecondLock) {
1008                    NetworkPolicy policy = mNetworkPolicy.get(template);
1009                    if (policy == null && meteredHint) {
1010                        // policy doesn't exist, and AP is hinting that it's
1011                        // metered: create an inferred policy.
1012                        policy = newWifiPolicy(template, meteredHint);
1013                        addNetworkPolicyAL(policy);
1014
1015                    } else if (policy != null && policy.inferred) {
1016                        // policy exists, and was inferred: update its current
1017                        // metered state.
1018                        policy.metered = meteredHint;
1019
1020                        // since this is inferred for each wifi session, just update
1021                        // rules without persisting.
1022                        updateNetworkRulesNL();
1023                    }
1024                }
1025            }
1026        }
1027    };
1028
1029    static NetworkPolicy newWifiPolicy(NetworkTemplate template, boolean metered) {
1030        return new NetworkPolicy(template, CYCLE_NONE, Time.TIMEZONE_UTC,
1031                WARNING_DISABLED, LIMIT_DISABLED, SNOOZE_NEVER, SNOOZE_NEVER,
1032                metered, true);
1033    }
1034
1035    /**
1036     * Observer that watches for {@link INetworkManagementService} alerts.
1037     */
1038    final private INetworkManagementEventObserver mAlertObserver
1039            = new BaseNetworkObserver() {
1040        @Override
1041        public void limitReached(String limitName, String iface) {
1042            // only someone like NMS should be calling us
1043            mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1044
1045            if (!LIMIT_GLOBAL_ALERT.equals(limitName)) {
1046                mHandler.obtainMessage(MSG_LIMIT_REACHED, iface).sendToTarget();
1047            }
1048        }
1049    };
1050
1051    /**
1052     * Check {@link NetworkPolicy} against current {@link INetworkStatsService}
1053     * to show visible notifications as needed.
1054     */
1055    void updateNotificationsNL() {
1056        if (LOGV) Slog.v(TAG, "updateNotificationsNL()");
1057
1058        // keep track of previously active notifications
1059        final ArraySet<NotificationId> beforeNotifs = new ArraySet<NotificationId>(mActiveNotifs);
1060        mActiveNotifs.clear();
1061
1062        // TODO: when switching to kernel notifications, compute next future
1063        // cycle boundary to recompute notifications.
1064
1065        // examine stats for each active policy
1066        final long currentTime = currentTimeMillis();
1067        for (int i = mNetworkPolicy.size()-1; i >= 0; i--) {
1068            final NetworkPolicy policy = mNetworkPolicy.valueAt(i);
1069            // ignore policies that aren't relevant to user
1070            if (!isTemplateRelevant(policy.template)) continue;
1071            if (!policy.hasCycle()) continue;
1072
1073            final long start = computeLastCycleBoundary(currentTime, policy);
1074            final long end = currentTime;
1075            final long totalBytes = getTotalBytes(policy.template, start, end);
1076
1077            if (policy.isOverLimit(totalBytes)) {
1078                if (policy.lastLimitSnooze >= start) {
1079                    enqueueNotification(policy, TYPE_LIMIT_SNOOZED, totalBytes);
1080                } else {
1081                    enqueueNotification(policy, TYPE_LIMIT, totalBytes);
1082                    notifyOverLimitNL(policy.template);
1083                }
1084
1085            } else {
1086                notifyUnderLimitNL(policy.template);
1087
1088                if (policy.isOverWarning(totalBytes) && policy.lastWarningSnooze < start) {
1089                    enqueueNotification(policy, TYPE_WARNING, totalBytes);
1090                }
1091            }
1092        }
1093
1094        // cancel stale notifications that we didn't renew above
1095        for (int i = beforeNotifs.size()-1; i >= 0; i--) {
1096            final NotificationId notificationId = beforeNotifs.valueAt(i);
1097            if (!mActiveNotifs.contains(notificationId)) {
1098                cancelNotification(notificationId);
1099            }
1100        }
1101    }
1102
1103    /**
1104     * Test if given {@link NetworkTemplate} is relevant to user based on
1105     * current device state, such as when
1106     * {@link TelephonyManager#getSubscriberId()} matches. This is regardless of
1107     * data connection status.
1108     */
1109    private boolean isTemplateRelevant(NetworkTemplate template) {
1110        if (template.isMatchRuleMobile()) {
1111            final TelephonyManager tele = TelephonyManager.from(mContext);
1112            final SubscriptionManager sub = SubscriptionManager.from(mContext);
1113
1114            // Mobile template is relevant when any active subscriber matches
1115            final int[] subIds = sub.getActiveSubscriptionIdList();
1116            for (int subId : subIds) {
1117                final String subscriberId = tele.getSubscriberId(subId);
1118                final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE,
1119                        TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true);
1120                if (template.matches(probeIdent)) {
1121                    return true;
1122                }
1123            }
1124            return false;
1125        } else {
1126            return true;
1127        }
1128    }
1129
1130    /**
1131     * Notify that given {@link NetworkTemplate} is over
1132     * {@link NetworkPolicy#limitBytes}, potentially showing dialog to user.
1133     */
1134    private void notifyOverLimitNL(NetworkTemplate template) {
1135        if (!mOverLimitNotified.contains(template)) {
1136            mContext.startActivity(buildNetworkOverLimitIntent(mContext.getResources(), template));
1137            mOverLimitNotified.add(template);
1138        }
1139    }
1140
1141    private void notifyUnderLimitNL(NetworkTemplate template) {
1142        mOverLimitNotified.remove(template);
1143    }
1144
1145    /**
1146     * Show notification for combined {@link NetworkPolicy} and specific type,
1147     * like {@link #TYPE_LIMIT}. Okay to call multiple times.
1148     */
1149    private void enqueueNotification(NetworkPolicy policy, int type, long totalBytes) {
1150        final NotificationId notificationId = new NotificationId(policy, type);
1151        final Notification.Builder builder =
1152                new Notification.Builder(mContext, SystemNotificationChannels.NETWORK_STATUS);
1153        builder.setOnlyAlertOnce(true);
1154        builder.setWhen(0L);
1155        builder.setColor(mContext.getColor(
1156                com.android.internal.R.color.system_notification_accent_color));
1157
1158        final Resources res = mContext.getResources();
1159        CharSequence body = null;
1160        switch (type) {
1161            case TYPE_WARNING: {
1162                final CharSequence title = res.getText(R.string.data_usage_warning_title);
1163                body = res.getString(R.string.data_usage_warning_body);
1164
1165                builder.setSmallIcon(R.drawable.stat_notify_error);
1166                builder.setTicker(title);
1167                builder.setContentTitle(title);
1168                builder.setContentText(body);
1169                builder.setDefaults(Notification.DEFAULT_ALL);
1170                builder.setChannelId(SystemNotificationChannels.NETWORK_ALERTS);
1171
1172                final Intent snoozeIntent = buildSnoozeWarningIntent(policy.template);
1173                builder.setDeleteIntent(PendingIntent.getBroadcast(
1174                        mContext, 0, snoozeIntent, PendingIntent.FLAG_UPDATE_CURRENT));
1175
1176                final Intent viewIntent = buildViewDataUsageIntent(res, policy.template);
1177                builder.setContentIntent(PendingIntent.getActivity(
1178                        mContext, 0, viewIntent, PendingIntent.FLAG_UPDATE_CURRENT));
1179
1180                break;
1181            }
1182            case TYPE_LIMIT: {
1183                body = res.getText(R.string.data_usage_limit_body);
1184
1185                final CharSequence title;
1186                int icon = R.drawable.stat_notify_disabled_data;
1187                switch (policy.template.getMatchRule()) {
1188                    case MATCH_MOBILE_3G_LOWER:
1189                        title = res.getText(R.string.data_usage_3g_limit_title);
1190                        break;
1191                    case MATCH_MOBILE_4G:
1192                        title = res.getText(R.string.data_usage_4g_limit_title);
1193                        break;
1194                    case MATCH_MOBILE_ALL:
1195                        title = res.getText(R.string.data_usage_mobile_limit_title);
1196                        break;
1197                    case MATCH_WIFI:
1198                        title = res.getText(R.string.data_usage_wifi_limit_title);
1199                        icon = R.drawable.stat_notify_error;
1200                        break;
1201                    default:
1202                        title = null;
1203                        break;
1204                }
1205
1206                builder.setOngoing(true);
1207                builder.setSmallIcon(icon);
1208                builder.setTicker(title);
1209                builder.setContentTitle(title);
1210                builder.setContentText(body);
1211
1212                final Intent intent = buildNetworkOverLimitIntent(res, policy.template);
1213                builder.setContentIntent(PendingIntent.getActivity(
1214                        mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT));
1215                break;
1216            }
1217            case TYPE_LIMIT_SNOOZED: {
1218                final long overBytes = totalBytes - policy.limitBytes;
1219                body = res.getString(R.string.data_usage_limit_snoozed_body,
1220                        Formatter.formatFileSize(mContext, overBytes));
1221
1222                final CharSequence title;
1223                switch (policy.template.getMatchRule()) {
1224                    case MATCH_MOBILE_3G_LOWER:
1225                        title = res.getText(R.string.data_usage_3g_limit_snoozed_title);
1226                        break;
1227                    case MATCH_MOBILE_4G:
1228                        title = res.getText(R.string.data_usage_4g_limit_snoozed_title);
1229                        break;
1230                    case MATCH_MOBILE_ALL:
1231                        title = res.getText(R.string.data_usage_mobile_limit_snoozed_title);
1232                        break;
1233                    case MATCH_WIFI:
1234                        title = res.getText(R.string.data_usage_wifi_limit_snoozed_title);
1235                        break;
1236                    default:
1237                        title = null;
1238                        break;
1239                }
1240
1241                builder.setOngoing(true);
1242                builder.setSmallIcon(R.drawable.stat_notify_error);
1243                builder.setTicker(title);
1244                builder.setContentTitle(title);
1245                builder.setContentText(body);
1246
1247                final Intent intent = buildViewDataUsageIntent(res, policy.template);
1248                builder.setContentIntent(PendingIntent.getActivity(
1249                        mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT));
1250                break;
1251            }
1252        }
1253
1254        // TODO: move to NotificationManager once we can mock it
1255        try {
1256            final String packageName = mContext.getPackageName();
1257            if (!TextUtils.isEmpty(body)) {
1258                builder.setStyle(new Notification.BigTextStyle()
1259                        .bigText(body));
1260            }
1261            mNotifManager.enqueueNotificationWithTag(
1262                    packageName, packageName, notificationId.getTag(), notificationId.getId(),
1263                    builder.build(), UserHandle.USER_ALL);
1264            mActiveNotifs.add(notificationId);
1265        } catch (RemoteException e) {
1266            // ignored; service lives in system_server
1267        }
1268    }
1269
1270    private void cancelNotification(NotificationId notificationId) {
1271        // TODO: move to NotificationManager once we can mock it
1272        try {
1273            final String packageName = mContext.getPackageName();
1274            mNotifManager.cancelNotificationWithTag(
1275                    packageName, notificationId.getTag(), notificationId.getId(),
1276                    UserHandle.USER_ALL);
1277        } catch (RemoteException e) {
1278            // ignored; service lives in system_server
1279        }
1280    }
1281
1282    /**
1283     * Receiver that watches for {@link IConnectivityManager} to claim network
1284     * interfaces. Used to apply {@link NetworkPolicy} to matching networks.
1285     */
1286    private BroadcastReceiver mConnReceiver = new BroadcastReceiver() {
1287        @Override
1288        public void onReceive(Context context, Intent intent) {
1289            // on background handler thread, and verified CONNECTIVITY_INTERNAL
1290            // permission above.
1291
1292            maybeRefreshTrustedTime();
1293            synchronized (mUidRulesFirstLock) {
1294                synchronized (mNetworkPoliciesSecondLock) {
1295                    ensureActiveMobilePolicyAL();
1296                    normalizePoliciesNL();
1297                    updateNetworkEnabledNL();
1298                    updateNetworkRulesNL();
1299                    updateNotificationsNL();
1300                }
1301            }
1302        }
1303    };
1304
1305    /**
1306     * Update mobile policies with data cycle information from {@link CarrierConfigManager}
1307     * if necessary.
1308     *
1309     * @param subId that has its associated NetworkPolicy updated if necessary
1310     * @return if any policies were updated
1311     */
1312    private boolean maybeUpdateMobilePolicyCycleNL(int subId) {
1313        if (LOGV) Slog.v(TAG, "maybeUpdateMobilePolicyCycleNL()");
1314        final PersistableBundle config = mCarrierConfigManager.getConfigForSubId(subId);
1315
1316        if (config == null) {
1317            return false;
1318        }
1319
1320        boolean policyUpdated = false;
1321        final String subscriberId = TelephonyManager.from(mContext).getSubscriberId(subId);
1322
1323        // find and update the mobile NetworkPolicy for this subscriber id
1324        final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE,
1325                TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true);
1326        for (int i = mNetworkPolicy.size() - 1; i >= 0; i--) {
1327            final NetworkTemplate template = mNetworkPolicy.keyAt(i);
1328            if (template.matches(probeIdent)) {
1329                NetworkPolicy policy = mNetworkPolicy.valueAt(i);
1330
1331                // only update the policy if the user didn't change any of the defaults.
1332                if (!policy.inferred) {
1333                    // TODO: inferred could be split, so that if a user changes their data limit or
1334                    // warning, it doesn't prevent their cycle date from being updated.
1335                    if (LOGD) Slog.v(TAG, "Didn't update NetworkPolicy because policy.inferred");
1336                    continue;
1337                }
1338
1339                final int cycleDay = getCycleDayFromCarrierConfig(config, policy.cycleDay);
1340                final long warningBytes = getWarningBytesFromCarrierConfig(config,
1341                        policy.warningBytes);
1342                final long limitBytes = getLimitBytesFromCarrierConfig(config,
1343                        policy.limitBytes);
1344
1345                if (policy.cycleDay == cycleDay &&
1346                        policy.warningBytes == warningBytes &&
1347                        policy.limitBytes == limitBytes) {
1348                    continue;
1349                }
1350
1351                policyUpdated = true;
1352                policy.cycleDay = cycleDay;
1353                policy.warningBytes = warningBytes;
1354                policy.limitBytes = limitBytes;
1355
1356                if (LOGD) {
1357                    Slog.d(TAG, "Updated NetworkPolicy " + policy + " which matches subscriber "
1358                            + NetworkIdentity.scrubSubscriberId(subscriberId)
1359                            + " from CarrierConfigManager");
1360                }
1361            }
1362        }
1363
1364        return policyUpdated;
1365    }
1366
1367    /**
1368     * Returns the cycle day that should be used for a mobile NetworkPolicy.
1369     *
1370     * It attempts to get an appropriate cycle day from the passed in CarrierConfig. If it's unable
1371     * to do so, it returns the fallback value.
1372     *
1373     * @param config The CarrierConfig to read the value from.
1374     * @param fallbackCycleDay to return if the CarrierConfig can't be read.
1375     * @return cycleDay to use in the mobile NetworkPolicy.
1376     */
1377    @VisibleForTesting
1378    public int getCycleDayFromCarrierConfig(@Nullable PersistableBundle config,
1379            int fallbackCycleDay) {
1380        if (config == null) {
1381            return fallbackCycleDay;
1382        }
1383        int cycleDay =
1384                config.getInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT);
1385        if (cycleDay == DATA_CYCLE_USE_PLATFORM_DEFAULT) {
1386            return fallbackCycleDay;
1387        }
1388        // validate cycleDay value
1389        final Calendar cal = Calendar.getInstance();
1390        if (cycleDay < cal.getMinimum(Calendar.DAY_OF_MONTH) ||
1391                cycleDay > cal.getMaximum(Calendar.DAY_OF_MONTH)) {
1392            Slog.e(TAG, "Invalid date in "
1393                    + "CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT: " + cycleDay);
1394            return fallbackCycleDay;
1395        }
1396        return cycleDay;
1397    }
1398
1399    /**
1400     * Returns the warning bytes that should be used for a mobile NetworkPolicy.
1401     *
1402     * It attempts to get an appropriate value from the passed in CarrierConfig. If it's unable
1403     * to do so, it returns the fallback value.
1404     *
1405     * @param config The CarrierConfig to read the value from.
1406     * @param fallbackWarningBytes to return if the CarrierConfig can't be read.
1407     * @return warningBytes to use in the mobile NetworkPolicy.
1408     */
1409    @VisibleForTesting
1410    public long getWarningBytesFromCarrierConfig(@Nullable PersistableBundle config,
1411            long fallbackWarningBytes) {
1412        if (config == null) {
1413            return fallbackWarningBytes;
1414        }
1415        long warningBytes =
1416                config.getLong(CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG);
1417
1418        if (warningBytes == DATA_CYCLE_THRESHOLD_DISABLED) {
1419            return WARNING_DISABLED;
1420        } else if (warningBytes == DATA_CYCLE_USE_PLATFORM_DEFAULT) {
1421            return getPlatformDefaultWarningBytes();
1422        } else if (warningBytes < 0) {
1423            Slog.e(TAG, "Invalid value in "
1424                    + "CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG; expected a "
1425                    + "non-negative value but got: " + warningBytes);
1426            return fallbackWarningBytes;
1427        }
1428
1429        return warningBytes;
1430    }
1431
1432    /**
1433     * Returns the limit bytes that should be used for a mobile NetworkPolicy.
1434     *
1435     * It attempts to get an appropriate value from the passed in CarrierConfig. If it's unable
1436     * to do so, it returns the fallback value.
1437     *
1438     * @param config The CarrierConfig to read the value from.
1439     * @param fallbackLimitBytes to return if the CarrierConfig can't be read.
1440     * @return limitBytes to use in the mobile NetworkPolicy.
1441     */
1442    @VisibleForTesting
1443    public long getLimitBytesFromCarrierConfig(@Nullable PersistableBundle config,
1444            long fallbackLimitBytes) {
1445        if (config == null) {
1446            return fallbackLimitBytes;
1447        }
1448        long limitBytes =
1449                config.getLong(CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG);
1450
1451        if (limitBytes == DATA_CYCLE_THRESHOLD_DISABLED) {
1452            return LIMIT_DISABLED;
1453        } else if (limitBytes == DATA_CYCLE_USE_PLATFORM_DEFAULT) {
1454            return getPlatformDefaultLimitBytes();
1455        } else if (limitBytes < 0) {
1456            Slog.e(TAG, "Invalid value in "
1457                    + "CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG; expected a "
1458                    + "non-negative value but got: " + limitBytes);
1459            return fallbackLimitBytes;
1460        }
1461        return limitBytes;
1462    }
1463
1464    /**
1465     * Receiver that watches for {@link CarrierConfigManager} to be changed.
1466     */
1467    private BroadcastReceiver mCarrierConfigReceiver = new BroadcastReceiver() {
1468        @Override
1469        public void onReceive(Context context, Intent intent) {
1470            // No need to do a permission check, because the ACTION_CARRIER_CONFIG_CHANGED
1471            // broadcast is protected and can't be spoofed. Runs on a background handler thread.
1472
1473            if (!intent.hasExtra(PhoneConstants.SUBSCRIPTION_KEY)) {
1474                return;
1475            }
1476            final int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY, -1);
1477            final TelephonyManager tele = TelephonyManager.from(mContext);
1478            final String subscriberId = tele.getSubscriberId(subId);
1479
1480            maybeRefreshTrustedTime();
1481            synchronized (mUidRulesFirstLock) {
1482                synchronized (mNetworkPoliciesSecondLock) {
1483                    final boolean added = ensureActiveMobilePolicyAL(subId, subscriberId);
1484                    if (added) return;
1485                    final boolean updated = maybeUpdateMobilePolicyCycleNL(subId);
1486                    if (!updated) return;
1487                    // update network and notification rules, as the data cycle changed and it's
1488                    // possible that we should be triggering warnings/limits now
1489                    handleNetworkPoliciesUpdateAL(true);
1490                }
1491            }
1492        }
1493    };
1494
1495    /**
1496     * Handles all tasks that need to be run after a new network policy has been set, or an existing
1497     * one has been updated.
1498     *
1499     * @param shouldNormalizePolicies true iff network policies need to be normalized after the
1500     *                                update.
1501     */
1502    void handleNetworkPoliciesUpdateAL(boolean shouldNormalizePolicies) {
1503        if (shouldNormalizePolicies) {
1504            normalizePoliciesNL();
1505        }
1506        updateNetworkEnabledNL();
1507        updateNetworkRulesNL();
1508        updateNotificationsNL();
1509        writePolicyAL();
1510    }
1511
1512    /**
1513     * Proactively control network data connections when they exceed
1514     * {@link NetworkPolicy#limitBytes}.
1515     */
1516    void updateNetworkEnabledNL() {
1517        if (LOGV) Slog.v(TAG, "updateNetworkEnabledNL()");
1518
1519        // TODO: reset any policy-disabled networks when any policy is removed
1520        // completely, which is currently rare case.
1521
1522        final long currentTime = currentTimeMillis();
1523        for (int i = mNetworkPolicy.size()-1; i >= 0; i--) {
1524            final NetworkPolicy policy = mNetworkPolicy.valueAt(i);
1525            // shortcut when policy has no limit
1526            if (policy.limitBytes == LIMIT_DISABLED || !policy.hasCycle()) {
1527                setNetworkTemplateEnabled(policy.template, true);
1528                continue;
1529            }
1530
1531            final long start = computeLastCycleBoundary(currentTime, policy);
1532            final long end = currentTime;
1533            final long totalBytes = getTotalBytes(policy.template, start, end);
1534
1535            // disable data connection when over limit and not snoozed
1536            final boolean overLimitWithoutSnooze = policy.isOverLimit(totalBytes)
1537                    && policy.lastLimitSnooze < start;
1538            final boolean networkEnabled = !overLimitWithoutSnooze;
1539
1540            setNetworkTemplateEnabled(policy.template, networkEnabled);
1541        }
1542    }
1543
1544    /**
1545     * Proactively disable networks that match the given
1546     * {@link NetworkTemplate}.
1547     */
1548    private void setNetworkTemplateEnabled(NetworkTemplate template, boolean enabled) {
1549        // TODO: reach into ConnectivityManager to proactively disable bringing
1550        // up this network, since we know that traffic will be blocked.
1551
1552        if (template.getMatchRule() == MATCH_MOBILE_ALL) {
1553            // If mobile data usage hits the limit or if the user resumes the data, we need to
1554            // notify telephony.
1555            final SubscriptionManager sm = SubscriptionManager.from(mContext);
1556            final TelephonyManager tm = TelephonyManager.from(mContext);
1557
1558            final int[] subIds = sm.getActiveSubscriptionIdList();
1559            for (int subId : subIds) {
1560                final String subscriberId = tm.getSubscriberId(subId);
1561                final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE,
1562                        TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true);
1563                // Template is matched when subscriber id matches.
1564                if (template.matches(probeIdent)) {
1565                    tm.setPolicyDataEnabled(enabled, subId);
1566                }
1567            }
1568        }
1569    }
1570
1571    /**
1572     * Examine all connected {@link NetworkState}, looking for
1573     * {@link NetworkPolicy} that need to be enforced. When matches found, set
1574     * remaining quota based on usage cycle and historical stats.
1575     */
1576    void updateNetworkRulesNL() {
1577        if (LOGV) Slog.v(TAG, "updateNetworkRulesNL()");
1578
1579        final NetworkState[] states;
1580        try {
1581            states = mConnManager.getAllNetworkState();
1582        } catch (RemoteException e) {
1583            // ignored; service lives in system_server
1584            return;
1585        }
1586
1587        // First, generate identities of all connected networks so we can
1588        // quickly compare them against all defined policies below.
1589        final ArrayList<Pair<String, NetworkIdentity>> connIdents = new ArrayList<>(states.length);
1590        final ArraySet<String> connIfaces = new ArraySet<String>(states.length);
1591        for (NetworkState state : states) {
1592            if (state.networkInfo != null && state.networkInfo.isConnected()) {
1593                final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state);
1594
1595                final String baseIface = state.linkProperties.getInterfaceName();
1596                if (baseIface != null) {
1597                    connIdents.add(Pair.create(baseIface, ident));
1598                }
1599
1600                // Stacked interfaces are considered to have same identity as
1601                // their parent network.
1602                final List<LinkProperties> stackedLinks = state.linkProperties.getStackedLinks();
1603                for (LinkProperties stackedLink : stackedLinks) {
1604                    final String stackedIface = stackedLink.getInterfaceName();
1605                    if (stackedIface != null) {
1606                        connIdents.add(Pair.create(stackedIface, ident));
1607                    }
1608                }
1609            }
1610        }
1611
1612        // Apply policies against all connected interfaces found above
1613        mNetworkRules.clear();
1614        final ArrayList<String> ifaceList = Lists.newArrayList();
1615        for (int i = mNetworkPolicy.size() - 1; i >= 0; i--) {
1616            final NetworkPolicy policy = mNetworkPolicy.valueAt(i);
1617
1618            ifaceList.clear();
1619            for (int j = connIdents.size() - 1; j >= 0; j--) {
1620                final Pair<String, NetworkIdentity> ident = connIdents.get(j);
1621                if (policy.template.matches(ident.second)) {
1622                    ifaceList.add(ident.first);
1623                }
1624            }
1625
1626            if (ifaceList.size() > 0) {
1627                final String[] ifaces = ifaceList.toArray(new String[ifaceList.size()]);
1628                mNetworkRules.put(policy, ifaces);
1629            }
1630        }
1631
1632        long lowestRule = Long.MAX_VALUE;
1633        final ArraySet<String> newMeteredIfaces = new ArraySet<String>(states.length);
1634
1635        // apply each policy that we found ifaces for; compute remaining data
1636        // based on current cycle and historical stats, and push to kernel.
1637        final long currentTime = currentTimeMillis();
1638        for (int i = mNetworkRules.size()-1; i >= 0; i--) {
1639            final NetworkPolicy policy = mNetworkRules.keyAt(i);
1640            final String[] ifaces = mNetworkRules.valueAt(i);
1641
1642            final long start;
1643            final long totalBytes;
1644            if (policy.hasCycle()) {
1645                start = computeLastCycleBoundary(currentTime, policy);
1646                totalBytes = getTotalBytes(policy.template, start, currentTime);
1647            } else {
1648                start = Long.MAX_VALUE;
1649                totalBytes = 0;
1650            }
1651
1652            if (LOGD) {
1653                Slog.d(TAG, "applying policy " + policy + " to ifaces " + Arrays.toString(ifaces));
1654            }
1655
1656            final boolean hasWarning = policy.warningBytes != LIMIT_DISABLED;
1657            final boolean hasLimit = policy.limitBytes != LIMIT_DISABLED;
1658            if (hasLimit || policy.metered) {
1659                final long quotaBytes;
1660                if (!hasLimit) {
1661                    // metered network, but no policy limit; we still need to
1662                    // restrict apps, so push really high quota.
1663                    quotaBytes = Long.MAX_VALUE;
1664                } else if (policy.lastLimitSnooze >= start) {
1665                    // snoozing past quota, but we still need to restrict apps,
1666                    // so push really high quota.
1667                    quotaBytes = Long.MAX_VALUE;
1668                } else {
1669                    // remaining "quota" bytes are based on total usage in
1670                    // current cycle. kernel doesn't like 0-byte rules, so we
1671                    // set 1-byte quota and disable the radio later.
1672                    quotaBytes = Math.max(1, policy.limitBytes - totalBytes);
1673                }
1674
1675                if (ifaces.length > 1) {
1676                    // TODO: switch to shared quota once NMS supports
1677                    Slog.w(TAG, "shared quota unsupported; generating rule for each iface");
1678                }
1679
1680                for (String iface : ifaces) {
1681                    // long quotaBytes split up into two ints to fit in message
1682                    mHandler.obtainMessage(MSG_UPDATE_INTERFACE_QUOTA,
1683                            (int) (quotaBytes >> 32), (int) (quotaBytes & 0xFFFFFFFF), iface)
1684                            .sendToTarget();
1685                    newMeteredIfaces.add(iface);
1686                }
1687            }
1688
1689            // keep track of lowest warning or limit of active policies
1690            if (hasWarning && policy.warningBytes < lowestRule) {
1691                lowestRule = policy.warningBytes;
1692            }
1693            if (hasLimit && policy.limitBytes < lowestRule) {
1694                lowestRule = policy.limitBytes;
1695            }
1696        }
1697
1698        for (int i = connIfaces.size()-1; i >= 0; i--) {
1699            String iface = connIfaces.valueAt(i);
1700            // long quotaBytes split up into two ints to fit in message
1701            mHandler.obtainMessage(MSG_UPDATE_INTERFACE_QUOTA,
1702                    (int) (Long.MAX_VALUE >> 32), (int) (Long.MAX_VALUE & 0xFFFFFFFF), iface)
1703                    .sendToTarget();
1704            newMeteredIfaces.add(iface);
1705        }
1706
1707        mHandler.obtainMessage(MSG_ADVISE_PERSIST_THRESHOLD, lowestRule).sendToTarget();
1708
1709        // remove quota on any trailing interfaces
1710        for (int i = mMeteredIfaces.size() - 1; i >= 0; i--) {
1711            final String iface = mMeteredIfaces.valueAt(i);
1712            if (!newMeteredIfaces.contains(iface)) {
1713                mHandler.obtainMessage(MSG_REMOVE_INTERFACE_QUOTA, iface)
1714                        .sendToTarget();
1715            }
1716        }
1717        mMeteredIfaces = newMeteredIfaces;
1718
1719        final String[] meteredIfaces = mMeteredIfaces.toArray(new String[mMeteredIfaces.size()]);
1720        mHandler.obtainMessage(MSG_METERED_IFACES_CHANGED, meteredIfaces).sendToTarget();
1721    }
1722
1723    /**
1724     * Once any {@link #mNetworkPolicy} are loaded from disk, ensure that we
1725     * have at least a default mobile policy defined.
1726     */
1727    private void ensureActiveMobilePolicyAL() {
1728        if (LOGV) Slog.v(TAG, "ensureActiveMobilePolicyAL()");
1729        if (mSuppressDefaultPolicy) return;
1730
1731        final TelephonyManager tele = TelephonyManager.from(mContext);
1732        final SubscriptionManager sub = SubscriptionManager.from(mContext);
1733
1734        final int[] subIds = sub.getActiveSubscriptionIdList();
1735        for (int subId : subIds) {
1736            final String subscriberId = tele.getSubscriberId(subId);
1737            ensureActiveMobilePolicyAL(subId, subscriberId);
1738        }
1739    }
1740
1741    /**
1742     * Once any {@link #mNetworkPolicy} are loaded from disk, ensure that we
1743     * have at least a default mobile policy defined.
1744     *
1745     * @param subId to build a default policy for
1746     * @param subscriberId that we check for an existing policy
1747     * @return true if a mobile network policy was added, or false one already existed.
1748     */
1749    private boolean ensureActiveMobilePolicyAL(int subId, String subscriberId) {
1750        // Poke around to see if we already have a policy
1751        final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE,
1752                TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true);
1753        for (int i = mNetworkPolicy.size() - 1; i >= 0; i--) {
1754            final NetworkTemplate template = mNetworkPolicy.keyAt(i);
1755            if (template.matches(probeIdent)) {
1756                if (LOGD) {
1757                    Slog.d(TAG, "Found template " + template + " which matches subscriber "
1758                            + NetworkIdentity.scrubSubscriberId(subscriberId));
1759                }
1760                return false;
1761            }
1762        }
1763
1764        Slog.i(TAG, "No policy for subscriber " + NetworkIdentity.scrubSubscriberId(subscriberId)
1765                + "; generating default policy");
1766        final NetworkPolicy policy = buildDefaultMobilePolicy(subId, subscriberId);
1767        addNetworkPolicyAL(policy);
1768        return true;
1769    }
1770
1771    private long getPlatformDefaultWarningBytes() {
1772        final int dataWarningConfig = mContext.getResources().getInteger(
1773                com.android.internal.R.integer.config_networkPolicyDefaultWarning);
1774        if (dataWarningConfig == WARNING_DISABLED) {
1775            return WARNING_DISABLED;
1776        } else {
1777            return dataWarningConfig * MB_IN_BYTES;
1778        }
1779    }
1780
1781    private long getPlatformDefaultLimitBytes() {
1782        return LIMIT_DISABLED;
1783    }
1784
1785    @VisibleForTesting
1786    public NetworkPolicy buildDefaultMobilePolicy(int subId, String subscriberId) {
1787        PersistableBundle config = mCarrierConfigManager.getConfigForSubId(subId);
1788
1789        // assume usage cycle starts today
1790        final Time time = new Time();
1791        time.setToNow();
1792
1793        final String cycleTimezone = time.timezone;
1794
1795        final int cycleDay = getCycleDayFromCarrierConfig(config, time.monthDay);
1796        final long warningBytes = getWarningBytesFromCarrierConfig(config,
1797                getPlatformDefaultWarningBytes());
1798        final long limitBytes = getLimitBytesFromCarrierConfig(config,
1799                getPlatformDefaultLimitBytes());
1800
1801        final NetworkTemplate template = buildTemplateMobileAll(subscriberId);
1802        final NetworkPolicy policy = new NetworkPolicy(template, cycleDay, cycleTimezone,
1803                warningBytes, limitBytes, SNOOZE_NEVER, SNOOZE_NEVER, true, true);
1804        return policy;
1805    }
1806
1807    private void readPolicyAL() {
1808        if (LOGV) Slog.v(TAG, "readPolicyAL()");
1809
1810        // clear any existing policy and read from disk
1811        mNetworkPolicy.clear();
1812        mUidPolicy.clear();
1813
1814        FileInputStream fis = null;
1815        try {
1816            fis = mPolicyFile.openRead();
1817            final XmlPullParser in = Xml.newPullParser();
1818            in.setInput(fis, StandardCharsets.UTF_8.name());
1819
1820             // Must save the <restrict-background> tags and convert them to <uid-policy> later,
1821             // to skip UIDs that were explicitly blacklisted.
1822            final SparseBooleanArray whitelistedRestrictBackground = new SparseBooleanArray();
1823
1824            int type;
1825            int version = VERSION_INIT;
1826            boolean insideWhitelist = false;
1827            while ((type = in.next()) != END_DOCUMENT) {
1828                final String tag = in.getName();
1829                if (type == START_TAG) {
1830                    if (TAG_POLICY_LIST.equals(tag)) {
1831                        final boolean oldValue = mRestrictBackground;
1832                        version = readIntAttribute(in, ATTR_VERSION);
1833                        if (version >= VERSION_ADDED_RESTRICT_BACKGROUND) {
1834                            mRestrictBackground = readBooleanAttribute(
1835                                    in, ATTR_RESTRICT_BACKGROUND);
1836                        } else {
1837                            mRestrictBackground = false;
1838                        }
1839                        if (mRestrictBackground != oldValue) {
1840                            // Some early services may have read the default value,
1841                            // so notify them that it's changed
1842                            mHandler.obtainMessage(MSG_RESTRICT_BACKGROUND_CHANGED,
1843                                    mRestrictBackground ? 1 : 0, 0).sendToTarget();
1844                        }
1845
1846                    } else if (TAG_NETWORK_POLICY.equals(tag)) {
1847                        final int networkTemplate = readIntAttribute(in, ATTR_NETWORK_TEMPLATE);
1848                        final String subscriberId = in.getAttributeValue(null, ATTR_SUBSCRIBER_ID);
1849                        final String networkId;
1850                        if (version >= VERSION_ADDED_NETWORK_ID) {
1851                            networkId = in.getAttributeValue(null, ATTR_NETWORK_ID);
1852                        } else {
1853                            networkId = null;
1854                        }
1855                        final int cycleDay = readIntAttribute(in, ATTR_CYCLE_DAY);
1856                        final String cycleTimezone;
1857                        if (version >= VERSION_ADDED_TIMEZONE) {
1858                            cycleTimezone = in.getAttributeValue(null, ATTR_CYCLE_TIMEZONE);
1859                        } else {
1860                            cycleTimezone = Time.TIMEZONE_UTC;
1861                        }
1862                        final long warningBytes = readLongAttribute(in, ATTR_WARNING_BYTES);
1863                        final long limitBytes = readLongAttribute(in, ATTR_LIMIT_BYTES);
1864                        final long lastLimitSnooze;
1865                        if (version >= VERSION_SPLIT_SNOOZE) {
1866                            lastLimitSnooze = readLongAttribute(in, ATTR_LAST_LIMIT_SNOOZE);
1867                        } else if (version >= VERSION_ADDED_SNOOZE) {
1868                            lastLimitSnooze = readLongAttribute(in, ATTR_LAST_SNOOZE);
1869                        } else {
1870                            lastLimitSnooze = SNOOZE_NEVER;
1871                        }
1872                        final boolean metered;
1873                        if (version >= VERSION_ADDED_METERED) {
1874                            metered = readBooleanAttribute(in, ATTR_METERED);
1875                        } else {
1876                            switch (networkTemplate) {
1877                                case MATCH_MOBILE_3G_LOWER:
1878                                case MATCH_MOBILE_4G:
1879                                case MATCH_MOBILE_ALL:
1880                                    metered = true;
1881                                    break;
1882                                default:
1883                                    metered = false;
1884                            }
1885                        }
1886                        final long lastWarningSnooze;
1887                        if (version >= VERSION_SPLIT_SNOOZE) {
1888                            lastWarningSnooze = readLongAttribute(in, ATTR_LAST_WARNING_SNOOZE);
1889                        } else {
1890                            lastWarningSnooze = SNOOZE_NEVER;
1891                        }
1892                        final boolean inferred;
1893                        if (version >= VERSION_ADDED_INFERRED) {
1894                            inferred = readBooleanAttribute(in, ATTR_INFERRED);
1895                        } else {
1896                            inferred = false;
1897                        }
1898
1899                        final NetworkTemplate template = new NetworkTemplate(networkTemplate,
1900                                subscriberId, networkId);
1901                        if (template.isPersistable()) {
1902                            mNetworkPolicy.put(template, new NetworkPolicy(template, cycleDay,
1903                                    cycleTimezone, warningBytes, limitBytes, lastWarningSnooze,
1904                                    lastLimitSnooze, metered, inferred));
1905                        }
1906
1907                    } else if (TAG_UID_POLICY.equals(tag)) {
1908                        final int uid = readIntAttribute(in, ATTR_UID);
1909                        final int policy = readIntAttribute(in, ATTR_POLICY);
1910
1911                        if (UserHandle.isApp(uid)) {
1912                            setUidPolicyUncheckedUL(uid, policy, false);
1913                        } else {
1914                            Slog.w(TAG, "unable to apply policy to UID " + uid + "; ignoring");
1915                        }
1916                    } else if (TAG_APP_POLICY.equals(tag)) {
1917                        final int appId = readIntAttribute(in, ATTR_APP_ID);
1918                        final int policy = readIntAttribute(in, ATTR_POLICY);
1919
1920                        // TODO: set for other users during upgrade
1921                        // app policy is deprecated so this is only used in pre system user split.
1922                        final int uid = UserHandle.getUid(UserHandle.USER_SYSTEM, appId);
1923                        if (UserHandle.isApp(uid)) {
1924                            setUidPolicyUncheckedUL(uid, policy, false);
1925                        } else {
1926                            Slog.w(TAG, "unable to apply policy to UID " + uid + "; ignoring");
1927                        }
1928                    } else if (TAG_WHITELIST.equals(tag)) {
1929                        insideWhitelist = true;
1930                    } else if (TAG_RESTRICT_BACKGROUND.equals(tag) && insideWhitelist) {
1931                        final int uid = readIntAttribute(in, ATTR_UID);
1932                        whitelistedRestrictBackground.append(uid, true);
1933                    } else if (TAG_REVOKED_RESTRICT_BACKGROUND.equals(tag) && insideWhitelist) {
1934                        final int uid = readIntAttribute(in, ATTR_UID);
1935                        mRestrictBackgroundWhitelistRevokedUids.put(uid, true);
1936                    }
1937                } else if (type == END_TAG) {
1938                    if (TAG_WHITELIST.equals(tag)) {
1939                        insideWhitelist = false;
1940                    }
1941
1942                }
1943            }
1944
1945            final int size = whitelistedRestrictBackground.size();
1946            for (int i = 0; i < size; i++) {
1947                final int uid = whitelistedRestrictBackground.keyAt(i);
1948                final int policy = mUidPolicy.get(uid, POLICY_NONE);
1949                if ((policy & POLICY_REJECT_METERED_BACKGROUND) != 0) {
1950                    Slog.w(TAG, "ignoring restrict-background-whitelist for " + uid
1951                            + " because its policy is " + uidPoliciesToString(policy));
1952                    continue;
1953                }
1954                if (UserHandle.isApp(uid)) {
1955                    final int newPolicy = policy | POLICY_ALLOW_METERED_BACKGROUND;
1956                    if (LOGV)
1957                        Log.v(TAG, "new policy for " + uid + ": " + uidPoliciesToString(newPolicy));
1958                    setUidPolicyUncheckedUL(uid, newPolicy, false);
1959                } else {
1960                    Slog.w(TAG, "unable to update policy on UID " + uid);
1961                }
1962            }
1963
1964        } catch (FileNotFoundException e) {
1965            // missing policy is okay, probably first boot
1966            upgradeLegacyBackgroundDataUL();
1967        } catch (IOException e) {
1968            Log.wtf(TAG, "problem reading network policy", e);
1969        } catch (XmlPullParserException e) {
1970            Log.wtf(TAG, "problem reading network policy", e);
1971        } finally {
1972            IoUtils.closeQuietly(fis);
1973        }
1974    }
1975
1976    /**
1977     * Upgrade legacy background data flags, notifying listeners of one last
1978     * change to always-true.
1979     */
1980    private void upgradeLegacyBackgroundDataUL() {
1981        mRestrictBackground = Settings.Secure.getInt(
1982                mContext.getContentResolver(), Settings.Secure.BACKGROUND_DATA, 1) != 1;
1983
1984        // kick off one last broadcast if restricted
1985        if (mRestrictBackground) {
1986            final Intent broadcast = new Intent(
1987                    ConnectivityManager.ACTION_BACKGROUND_DATA_SETTING_CHANGED);
1988            mContext.sendBroadcastAsUser(broadcast, UserHandle.ALL);
1989        }
1990    }
1991
1992    void writePolicyAL() {
1993        if (LOGV) Slog.v(TAG, "writePolicyAL()");
1994
1995        FileOutputStream fos = null;
1996        try {
1997            fos = mPolicyFile.startWrite();
1998
1999            XmlSerializer out = new FastXmlSerializer();
2000            out.setOutput(fos, StandardCharsets.UTF_8.name());
2001            out.startDocument(null, true);
2002
2003            out.startTag(null, TAG_POLICY_LIST);
2004            writeIntAttribute(out, ATTR_VERSION, VERSION_LATEST);
2005            writeBooleanAttribute(out, ATTR_RESTRICT_BACKGROUND, mRestrictBackground);
2006
2007            // write all known network policies
2008            for (int i = 0; i < mNetworkPolicy.size(); i++) {
2009                final NetworkPolicy policy = mNetworkPolicy.valueAt(i);
2010                final NetworkTemplate template = policy.template;
2011                if (!template.isPersistable()) continue;
2012
2013                out.startTag(null, TAG_NETWORK_POLICY);
2014                writeIntAttribute(out, ATTR_NETWORK_TEMPLATE, template.getMatchRule());
2015                final String subscriberId = template.getSubscriberId();
2016                if (subscriberId != null) {
2017                    out.attribute(null, ATTR_SUBSCRIBER_ID, subscriberId);
2018                }
2019                final String networkId = template.getNetworkId();
2020                if (networkId != null) {
2021                    out.attribute(null, ATTR_NETWORK_ID, networkId);
2022                }
2023                writeIntAttribute(out, ATTR_CYCLE_DAY, policy.cycleDay);
2024                out.attribute(null, ATTR_CYCLE_TIMEZONE, policy.cycleTimezone);
2025                writeLongAttribute(out, ATTR_WARNING_BYTES, policy.warningBytes);
2026                writeLongAttribute(out, ATTR_LIMIT_BYTES, policy.limitBytes);
2027                writeLongAttribute(out, ATTR_LAST_WARNING_SNOOZE, policy.lastWarningSnooze);
2028                writeLongAttribute(out, ATTR_LAST_LIMIT_SNOOZE, policy.lastLimitSnooze);
2029                writeBooleanAttribute(out, ATTR_METERED, policy.metered);
2030                writeBooleanAttribute(out, ATTR_INFERRED, policy.inferred);
2031                out.endTag(null, TAG_NETWORK_POLICY);
2032            }
2033
2034            // write all known uid policies
2035            for (int i = 0; i < mUidPolicy.size(); i++) {
2036                final int uid = mUidPolicy.keyAt(i);
2037                final int policy = mUidPolicy.valueAt(i);
2038
2039                // skip writing empty policies
2040                if (policy == POLICY_NONE) continue;
2041
2042                out.startTag(null, TAG_UID_POLICY);
2043                writeIntAttribute(out, ATTR_UID, uid);
2044                writeIntAttribute(out, ATTR_POLICY, policy);
2045                out.endTag(null, TAG_UID_POLICY);
2046            }
2047
2048            out.endTag(null, TAG_POLICY_LIST);
2049
2050            // write all whitelists
2051            out.startTag(null, TAG_WHITELIST);
2052
2053            // revoked restrict background whitelist
2054            int size = mRestrictBackgroundWhitelistRevokedUids.size();
2055            for (int i = 0; i < size; i++) {
2056                final int uid = mRestrictBackgroundWhitelistRevokedUids.keyAt(i);
2057                out.startTag(null, TAG_REVOKED_RESTRICT_BACKGROUND);
2058                writeIntAttribute(out, ATTR_UID, uid);
2059                out.endTag(null, TAG_REVOKED_RESTRICT_BACKGROUND);
2060            }
2061
2062            out.endTag(null, TAG_WHITELIST);
2063
2064            out.endDocument();
2065
2066            mPolicyFile.finishWrite(fos);
2067        } catch (IOException e) {
2068            if (fos != null) {
2069                mPolicyFile.failWrite(fos);
2070            }
2071        }
2072    }
2073
2074    @Override
2075    public void setUidPolicy(int uid, int policy) {
2076        mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
2077
2078        if (!UserHandle.isApp(uid)) {
2079            throw new IllegalArgumentException("cannot apply policy to UID " + uid);
2080        }
2081        synchronized (mUidRulesFirstLock) {
2082            final long token = Binder.clearCallingIdentity();
2083            try {
2084                final int oldPolicy = mUidPolicy.get(uid, POLICY_NONE);
2085                if (oldPolicy != policy) {
2086                    setUidPolicyUncheckedUL(uid, oldPolicy, policy, true);
2087                }
2088            } finally {
2089                Binder.restoreCallingIdentity(token);
2090            }
2091        }
2092    }
2093
2094    @Override
2095    public void addUidPolicy(int uid, int policy) {
2096        mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
2097
2098        if (!UserHandle.isApp(uid)) {
2099            throw new IllegalArgumentException("cannot apply policy to UID " + uid);
2100        }
2101
2102        synchronized (mUidRulesFirstLock) {
2103            final int oldPolicy = mUidPolicy.get(uid, POLICY_NONE);
2104            policy |= oldPolicy;
2105            if (oldPolicy != policy) {
2106                setUidPolicyUncheckedUL(uid, oldPolicy, policy, true);
2107            }
2108        }
2109    }
2110
2111    @Override
2112    public void removeUidPolicy(int uid, int policy) {
2113        mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
2114
2115        if (!UserHandle.isApp(uid)) {
2116            throw new IllegalArgumentException("cannot apply policy to UID " + uid);
2117        }
2118
2119        synchronized (mUidRulesFirstLock) {
2120            final int oldPolicy = mUidPolicy.get(uid, POLICY_NONE);
2121            policy = oldPolicy & ~policy;
2122            if (oldPolicy != policy) {
2123                setUidPolicyUncheckedUL(uid, oldPolicy, policy, true);
2124            }
2125        }
2126    }
2127
2128    private void setUidPolicyUncheckedUL(int uid, int oldPolicy, int policy, boolean persist) {
2129        setUidPolicyUncheckedUL(uid, policy, persist);
2130
2131        final boolean notifyApp;
2132        if (!isUidValidForWhitelistRules(uid)) {
2133            notifyApp = false;
2134        } else {
2135            final boolean wasBlacklisted = oldPolicy == POLICY_REJECT_METERED_BACKGROUND;
2136            final boolean isBlacklisted = policy == POLICY_REJECT_METERED_BACKGROUND;
2137            final boolean wasWhitelisted = oldPolicy == POLICY_ALLOW_METERED_BACKGROUND;
2138            final boolean isWhitelisted = policy == POLICY_ALLOW_METERED_BACKGROUND;
2139            final boolean wasBlocked = wasBlacklisted || (mRestrictBackground && !wasWhitelisted);
2140            final boolean isBlocked = isBlacklisted || (mRestrictBackground && !isWhitelisted);
2141            if ((wasWhitelisted && (!isWhitelisted || isBlacklisted))
2142                    && mDefaultRestrictBackgroundWhitelistUids.get(uid)
2143                    && !mRestrictBackgroundWhitelistRevokedUids.get(uid)) {
2144                if (LOGD)
2145                    Slog.d(TAG, "Adding uid " + uid + " to revoked restrict background whitelist");
2146                mRestrictBackgroundWhitelistRevokedUids.append(uid, true);
2147            }
2148            notifyApp = wasBlocked != isBlocked;
2149        }
2150        mHandler.obtainMessage(MSG_POLICIES_CHANGED, uid, policy, Boolean.valueOf(notifyApp))
2151                .sendToTarget();
2152    }
2153
2154    private void setUidPolicyUncheckedUL(int uid, int policy, boolean persist) {
2155        if (policy == POLICY_NONE) {
2156            mUidPolicy.delete(uid);
2157        } else {
2158            mUidPolicy.put(uid, policy);
2159        }
2160
2161        // uid policy changed, recompute rules and persist policy.
2162        updateRulesForDataUsageRestrictionsUL(uid);
2163        if (persist) {
2164            synchronized (mNetworkPoliciesSecondLock) {
2165                writePolicyAL();
2166            }
2167        }
2168    }
2169
2170    @Override
2171    public int getUidPolicy(int uid) {
2172        mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
2173
2174        synchronized (mUidRulesFirstLock) {
2175            return mUidPolicy.get(uid, POLICY_NONE);
2176        }
2177    }
2178
2179    @Override
2180    public int[] getUidsWithPolicy(int policy) {
2181        mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
2182
2183        int[] uids = new int[0];
2184        synchronized (mUidRulesFirstLock) {
2185            for (int i = 0; i < mUidPolicy.size(); i++) {
2186                final int uid = mUidPolicy.keyAt(i);
2187                final int uidPolicy = mUidPolicy.valueAt(i);
2188                if ((policy == POLICY_NONE && uidPolicy == POLICY_NONE) ||
2189                        (uidPolicy & policy) != 0) {
2190                    uids = appendInt(uids, uid);
2191                }
2192            }
2193        }
2194        return uids;
2195    }
2196
2197    /**
2198     * Removes any persistable state associated with given {@link UserHandle}, persisting
2199     * if any changes that are made.
2200     */
2201    boolean removeUserStateUL(int userId, boolean writePolicy) {
2202
2203        if (LOGV) Slog.v(TAG, "removeUserStateUL()");
2204        boolean changed = false;
2205
2206        // Remove entries from revoked default restricted background UID whitelist
2207        for (int i = mRestrictBackgroundWhitelistRevokedUids.size() - 1; i >= 0; i--) {
2208            final int uid = mRestrictBackgroundWhitelistRevokedUids.keyAt(i);
2209            if (UserHandle.getUserId(uid) == userId) {
2210                mRestrictBackgroundWhitelistRevokedUids.removeAt(i);
2211                changed = true;
2212            }
2213        }
2214
2215        // Remove associated UID policies
2216        int[] uids = new int[0];
2217        for (int i = 0; i < mUidPolicy.size(); i++) {
2218            final int uid = mUidPolicy.keyAt(i);
2219            if (UserHandle.getUserId(uid) == userId) {
2220                uids = appendInt(uids, uid);
2221            }
2222        }
2223
2224        if (uids.length > 0) {
2225            for (int uid : uids) {
2226                mUidPolicy.delete(uid);
2227            }
2228            changed = true;
2229        }
2230        synchronized (mNetworkPoliciesSecondLock) {
2231            updateRulesForGlobalChangeAL(true);
2232            if (writePolicy && changed) {
2233                writePolicyAL();
2234            }
2235        }
2236        return changed;
2237    }
2238
2239    @Override
2240    public void registerListener(INetworkPolicyListener listener) {
2241        // TODO: create permission for observing network policy
2242        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
2243        mListeners.register(listener);
2244    }
2245
2246    @Override
2247    public void unregisterListener(INetworkPolicyListener listener) {
2248        // TODO: create permission for observing network policy
2249        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
2250        mListeners.unregister(listener);
2251    }
2252
2253    @Override
2254    public void setNetworkPolicies(NetworkPolicy[] policies) {
2255        mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
2256
2257        final long token = Binder.clearCallingIdentity();
2258        try {
2259            maybeRefreshTrustedTime();
2260            synchronized (mUidRulesFirstLock) {
2261                synchronized (mNetworkPoliciesSecondLock) {
2262                    normalizePoliciesNL(policies);
2263                    handleNetworkPoliciesUpdateAL(false);
2264                }
2265            }
2266        } finally {
2267            Binder.restoreCallingIdentity(token);
2268        }
2269    }
2270
2271    void addNetworkPolicyAL(NetworkPolicy policy) {
2272        NetworkPolicy[] policies = getNetworkPolicies(mContext.getOpPackageName());
2273        policies = ArrayUtils.appendElement(NetworkPolicy.class, policies, policy);
2274        setNetworkPolicies(policies);
2275    }
2276
2277    @Override
2278    public NetworkPolicy[] getNetworkPolicies(String callingPackage) {
2279        mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
2280        try {
2281            mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE, TAG);
2282            // SKIP checking run-time OP_READ_PHONE_STATE since caller or self has PRIVILEGED
2283            // permission
2284        } catch (SecurityException e) {
2285            mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, TAG);
2286
2287            if (mAppOps.noteOp(AppOpsManager.OP_READ_PHONE_STATE, Binder.getCallingUid(),
2288                    callingPackage) != AppOpsManager.MODE_ALLOWED) {
2289                return new NetworkPolicy[0];
2290            }
2291        }
2292
2293        synchronized (mNetworkPoliciesSecondLock) {
2294            final int size = mNetworkPolicy.size();
2295            final NetworkPolicy[] policies = new NetworkPolicy[size];
2296            for (int i = 0; i < size; i++) {
2297                policies[i] = mNetworkPolicy.valueAt(i);
2298            }
2299            return policies;
2300        }
2301    }
2302
2303    private void normalizePoliciesNL() {
2304        normalizePoliciesNL(getNetworkPolicies(mContext.getOpPackageName()));
2305    }
2306
2307    private void normalizePoliciesNL(NetworkPolicy[] policies) {
2308        final TelephonyManager tele = TelephonyManager.from(mContext);
2309        final String[] merged = tele.getMergedSubscriberIds();
2310
2311        mNetworkPolicy.clear();
2312        for (NetworkPolicy policy : policies) {
2313            // When two normalized templates conflict, prefer the most
2314            // restrictive policy
2315            policy.template = NetworkTemplate.normalize(policy.template, merged);
2316            final NetworkPolicy existing = mNetworkPolicy.get(policy.template);
2317            if (existing == null || existing.compareTo(policy) > 0) {
2318                if (existing != null) {
2319                    Slog.d(TAG, "Normalization replaced " + existing + " with " + policy);
2320                }
2321                mNetworkPolicy.put(policy.template, policy);
2322            }
2323        }
2324    }
2325
2326    @Override
2327    public void snoozeLimit(NetworkTemplate template) {
2328        mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
2329
2330        final long token = Binder.clearCallingIdentity();
2331        try {
2332            performSnooze(template, TYPE_LIMIT);
2333        } finally {
2334            Binder.restoreCallingIdentity(token);
2335        }
2336    }
2337
2338    void performSnooze(NetworkTemplate template, int type) {
2339        maybeRefreshTrustedTime();
2340        final long currentTime = currentTimeMillis();
2341        synchronized (mUidRulesFirstLock) {
2342            synchronized (mNetworkPoliciesSecondLock) {
2343                // find and snooze local policy that matches
2344                final NetworkPolicy policy = mNetworkPolicy.get(template);
2345                if (policy == null) {
2346                    throw new IllegalArgumentException("unable to find policy for " + template);
2347                }
2348
2349                switch (type) {
2350                    case TYPE_WARNING:
2351                        policy.lastWarningSnooze = currentTime;
2352                        break;
2353                    case TYPE_LIMIT:
2354                        policy.lastLimitSnooze = currentTime;
2355                        break;
2356                    default:
2357                        throw new IllegalArgumentException("unexpected type");
2358                }
2359
2360                handleNetworkPoliciesUpdateAL(true);
2361            }
2362        }
2363    }
2364
2365    @Override
2366    public void onTetheringChanged(String iface, boolean tethering) {
2367        // No need to enforce permission because setRestrictBackground() will do it.
2368        if (LOGD) Log.d(TAG, "onTetherStateChanged(" + iface + ", " + tethering + ")");
2369        synchronized (mUidRulesFirstLock) {
2370            if (mRestrictBackground && tethering) {
2371                Log.d(TAG, "Tethering on (" + iface +"); disable Data Saver");
2372                setRestrictBackground(false);
2373            }
2374        }
2375    }
2376
2377    @Override
2378    public void setRestrictBackground(boolean restrictBackground) {
2379        Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "setRestrictBackground");
2380        try {
2381            mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
2382            final long token = Binder.clearCallingIdentity();
2383            try {
2384                maybeRefreshTrustedTime();
2385                synchronized (mUidRulesFirstLock) {
2386                    if (restrictBackground == mRestrictBackground) {
2387                        // Ideally, UI should never allow this scenario...
2388                        Slog.w(TAG, "setRestrictBackground: already " + restrictBackground);
2389                        return;
2390                    }
2391                    setRestrictBackgroundUL(restrictBackground);
2392                }
2393
2394            } finally {
2395                Binder.restoreCallingIdentity(token);
2396            }
2397
2398            mHandler.obtainMessage(MSG_RESTRICT_BACKGROUND_CHANGED, restrictBackground ? 1 : 0, 0)
2399                    .sendToTarget();
2400        } finally {
2401            Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
2402        }
2403    }
2404
2405    private void setRestrictBackgroundUL(boolean restrictBackground) {
2406        Slog.d(TAG, "setRestrictBackgroundUL(): " + restrictBackground);
2407        final boolean oldRestrictBackground = mRestrictBackground;
2408        mRestrictBackground = restrictBackground;
2409        // Must whitelist foreground apps before turning data saver mode on.
2410        // TODO: there is no need to iterate through all apps here, just those in the foreground,
2411        // so it could call AM to get the UIDs of such apps, and iterate through them instead.
2412        updateRulesForRestrictBackgroundUL();
2413        try {
2414            if (!mNetworkManager.setDataSaverModeEnabled(mRestrictBackground)) {
2415                Slog.e(TAG, "Could not change Data Saver Mode on NMS to " + mRestrictBackground);
2416                mRestrictBackground = oldRestrictBackground;
2417                // TODO: if it knew the foreground apps (see TODO above), it could call
2418                // updateRulesForRestrictBackgroundUL() again to restore state.
2419                return;
2420            }
2421        } catch (RemoteException e) {
2422            // ignored; service lives in system_server
2423        }
2424
2425        if (mRestrictBackgroundPowerState.globalBatterySaverEnabled) {
2426            mRestrictBackgroundChangedInBsm = true;
2427        }
2428        synchronized (mNetworkPoliciesSecondLock) {
2429            updateNotificationsNL();
2430            writePolicyAL();
2431        }
2432    }
2433
2434    @Override
2435    public int getRestrictBackgroundByCaller() {
2436        mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG);
2437        final int uid = Binder.getCallingUid();
2438
2439        synchronized (mUidRulesFirstLock) {
2440            // Must clear identity because getUidPolicy() is restricted to system.
2441            final long token = Binder.clearCallingIdentity();
2442            final int policy;
2443            try {
2444                policy = getUidPolicy(uid);
2445            } finally {
2446                Binder.restoreCallingIdentity(token);
2447            }
2448            if (policy == POLICY_REJECT_METERED_BACKGROUND) {
2449                // App is blacklisted.
2450                return RESTRICT_BACKGROUND_STATUS_ENABLED;
2451            }
2452            if (!mRestrictBackground) {
2453                return RESTRICT_BACKGROUND_STATUS_DISABLED;
2454            }
2455            return (mUidPolicy.get(uid) & POLICY_ALLOW_METERED_BACKGROUND) != 0
2456                    ? RESTRICT_BACKGROUND_STATUS_WHITELISTED
2457                    : RESTRICT_BACKGROUND_STATUS_ENABLED;
2458        }
2459    }
2460
2461    @Override
2462    public boolean getRestrictBackground() {
2463        mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
2464
2465        synchronized (mUidRulesFirstLock) {
2466            return mRestrictBackground;
2467        }
2468    }
2469
2470    @Override
2471    public void setDeviceIdleMode(boolean enabled) {
2472        mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
2473        Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "setDeviceIdleMode");
2474        try {
2475            synchronized (mUidRulesFirstLock) {
2476                if (mDeviceIdleMode == enabled) {
2477                    return;
2478                }
2479                mDeviceIdleMode = enabled;
2480                if (mSystemReady) {
2481                    // Device idle change means we need to rebuild rules for all
2482                    // known apps, so do a global refresh.
2483                    updateRulesForRestrictPowerUL();
2484                }
2485            }
2486            if (enabled) {
2487                EventLogTags.writeDeviceIdleOnPhase("net");
2488            } else {
2489                EventLogTags.writeDeviceIdleOffPhase("net");
2490            }
2491        } finally {
2492            Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
2493        }
2494    }
2495
2496    private NetworkPolicy findPolicyForNetworkNL(NetworkIdentity ident) {
2497        for (int i = mNetworkPolicy.size()-1; i >= 0; i--) {
2498            NetworkPolicy policy = mNetworkPolicy.valueAt(i);
2499            if (policy.template.matches(ident)) {
2500                return policy;
2501            }
2502        }
2503        return null;
2504    }
2505
2506    @Override
2507    public NetworkQuotaInfo getNetworkQuotaInfo(NetworkState state) {
2508        mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG);
2509
2510        // only returns usage summary, so we don't require caller to have
2511        // READ_NETWORK_USAGE_HISTORY.
2512        final long token = Binder.clearCallingIdentity();
2513        try {
2514            return getNetworkQuotaInfoUnchecked(state);
2515        } finally {
2516            Binder.restoreCallingIdentity(token);
2517        }
2518    }
2519
2520    private NetworkQuotaInfo getNetworkQuotaInfoUnchecked(NetworkState state) {
2521        final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state);
2522
2523        final NetworkPolicy policy;
2524        synchronized (mNetworkPoliciesSecondLock) {
2525            policy = findPolicyForNetworkNL(ident);
2526        }
2527
2528        if (policy == null || !policy.hasCycle()) {
2529            // missing policy means we can't derive useful quota info
2530            return null;
2531        }
2532
2533        final long currentTime = currentTimeMillis();
2534
2535        // find total bytes used under policy
2536        final long start = computeLastCycleBoundary(currentTime, policy);
2537        final long end = currentTime;
2538        final long totalBytes = getTotalBytes(policy.template, start, end);
2539
2540        // report soft and hard limits under policy
2541        final long softLimitBytes = policy.warningBytes != WARNING_DISABLED ? policy.warningBytes
2542                : NetworkQuotaInfo.NO_LIMIT;
2543        final long hardLimitBytes = policy.limitBytes != LIMIT_DISABLED ? policy.limitBytes
2544                : NetworkQuotaInfo.NO_LIMIT;
2545
2546        return new NetworkQuotaInfo(totalBytes, softLimitBytes, hardLimitBytes);
2547    }
2548
2549    @Override
2550    public boolean isNetworkMetered(NetworkState state) {
2551        if (state.networkInfo == null) {
2552            return false;
2553        }
2554
2555        final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state);
2556
2557        final NetworkPolicy policy;
2558        synchronized (mNetworkPoliciesSecondLock) {
2559            policy = findPolicyForNetworkNL(ident);
2560        }
2561
2562        if (policy != null) {
2563            return policy.metered;
2564        } else {
2565            final int type = state.networkInfo.getType();
2566            if ((isNetworkTypeMobile(type) && ident.getMetered()) || type == TYPE_WIMAX) {
2567                return true;
2568            }
2569            return false;
2570        }
2571    }
2572
2573    @Override
2574    protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
2575        if (!DumpUtils.checkDumpPermission(mContext, TAG, writer)) return;
2576
2577        final IndentingPrintWriter fout = new IndentingPrintWriter(writer, "  ");
2578
2579        final ArraySet<String> argSet = new ArraySet<String>(args.length);
2580        for (String arg : args) {
2581            argSet.add(arg);
2582        }
2583
2584        synchronized (mUidRulesFirstLock) {
2585            synchronized (mNetworkPoliciesSecondLock) {
2586                if (argSet.contains("--unsnooze")) {
2587                    for (int i = mNetworkPolicy.size()-1; i >= 0; i--) {
2588                        mNetworkPolicy.valueAt(i).clearSnooze();
2589                    }
2590
2591                    handleNetworkPoliciesUpdateAL(true);
2592
2593                    fout.println("Cleared snooze timestamps");
2594                    return;
2595                }
2596
2597                fout.print("System ready: "); fout.println(mSystemReady);
2598                fout.print("Restrict background: "); fout.println(mRestrictBackground);
2599                fout.print("Restrict power: "); fout.println(mRestrictPower);
2600                fout.print("Device idle: "); fout.println(mDeviceIdleMode);
2601                fout.println("Network policies:");
2602                fout.increaseIndent();
2603                for (int i = 0; i < mNetworkPolicy.size(); i++) {
2604                    fout.println(mNetworkPolicy.valueAt(i).toString());
2605                }
2606                fout.decreaseIndent();
2607
2608                fout.print("Metered ifaces: "); fout.println(String.valueOf(mMeteredIfaces));
2609
2610                fout.println("Policy for UIDs:");
2611                fout.increaseIndent();
2612                int size = mUidPolicy.size();
2613                for (int i = 0; i < size; i++) {
2614                    final int uid = mUidPolicy.keyAt(i);
2615                    final int policy = mUidPolicy.valueAt(i);
2616                    fout.print("UID=");
2617                    fout.print(uid);
2618                    fout.print(" policy=");
2619                    fout.print(uidPoliciesToString(policy));
2620                    fout.println();
2621                }
2622                fout.decreaseIndent();
2623
2624                size = mPowerSaveWhitelistExceptIdleAppIds.size();
2625                if (size > 0) {
2626                    fout.println("Power save whitelist (except idle) app ids:");
2627                    fout.increaseIndent();
2628                    for (int i = 0; i < size; i++) {
2629                        fout.print("UID=");
2630                        fout.print(mPowerSaveWhitelistExceptIdleAppIds.keyAt(i));
2631                        fout.print(": ");
2632                        fout.print(mPowerSaveWhitelistExceptIdleAppIds.valueAt(i));
2633                        fout.println();
2634                    }
2635                    fout.decreaseIndent();
2636                }
2637
2638                size = mPowerSaveWhitelistAppIds.size();
2639                if (size > 0) {
2640                    fout.println("Power save whitelist app ids:");
2641                    fout.increaseIndent();
2642                    for (int i = 0; i < size; i++) {
2643                        fout.print("UID=");
2644                        fout.print(mPowerSaveWhitelistAppIds.keyAt(i));
2645                        fout.print(": ");
2646                        fout.print(mPowerSaveWhitelistAppIds.valueAt(i));
2647                        fout.println();
2648                    }
2649                    fout.decreaseIndent();
2650                }
2651
2652                size = mDefaultRestrictBackgroundWhitelistUids.size();
2653                if (size > 0) {
2654                    fout.println("Default restrict background whitelist uids:");
2655                    fout.increaseIndent();
2656                    for (int i = 0; i < size; i++) {
2657                        fout.print("UID=");
2658                        fout.print(mDefaultRestrictBackgroundWhitelistUids.keyAt(i));
2659                        fout.println();
2660                    }
2661                    fout.decreaseIndent();
2662                }
2663
2664                size = mRestrictBackgroundWhitelistRevokedUids.size();
2665                if (size > 0) {
2666                    fout.println("Default restrict background whitelist uids revoked by users:");
2667                    fout.increaseIndent();
2668                    for (int i = 0; i < size; i++) {
2669                        fout.print("UID=");
2670                        fout.print(mRestrictBackgroundWhitelistRevokedUids.keyAt(i));
2671                        fout.println();
2672                    }
2673                    fout.decreaseIndent();
2674                }
2675
2676                final SparseBooleanArray knownUids = new SparseBooleanArray();
2677                collectKeys(mUidState, knownUids);
2678                collectKeys(mUidRules, knownUids);
2679
2680                fout.println("Status for all known UIDs:");
2681                fout.increaseIndent();
2682                size = knownUids.size();
2683                for (int i = 0; i < size; i++) {
2684                    final int uid = knownUids.keyAt(i);
2685                    fout.print("UID=");
2686                    fout.print(uid);
2687
2688                    final int state = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
2689                    fout.print(" state=");
2690                    fout.print(state);
2691                    if (state <= ActivityManager.PROCESS_STATE_TOP) {
2692                        fout.print(" (fg)");
2693                    } else {
2694                        fout.print(state <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
2695                                ? " (fg svc)" : " (bg)");
2696                    }
2697
2698                    final int uidRules = mUidRules.get(uid, RULE_NONE);
2699                    fout.print(" rules=");
2700                    fout.print(uidRulesToString(uidRules));
2701                    fout.println();
2702                }
2703                fout.decreaseIndent();
2704
2705                fout.println("Status for just UIDs with rules:");
2706                fout.increaseIndent();
2707                size = mUidRules.size();
2708                for (int i = 0; i < size; i++) {
2709                    final int uid = mUidRules.keyAt(i);
2710                    fout.print("UID=");
2711                    fout.print(uid);
2712                    final int uidRules = mUidRules.get(uid, RULE_NONE);
2713                    fout.print(" rules=");
2714                    fout.print(uidRulesToString(uidRules));
2715                    fout.println();
2716                }
2717                fout.decreaseIndent();
2718
2719                fout.println("Observed uid state changes:");
2720                fout.increaseIndent();
2721                mObservedHistory.dumpUL(fout);
2722                fout.decreaseIndent();
2723            }
2724        }
2725    }
2726
2727    @Override
2728    public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
2729            String[] args, ShellCallback callback, ResultReceiver resultReceiver) {
2730        (new NetworkPolicyManagerShellCommand(mContext, this)).exec(
2731                this, in, out, err, args, callback, resultReceiver);
2732    }
2733
2734    @Override
2735    public boolean isUidForeground(int uid) {
2736        mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
2737
2738        synchronized (mUidRulesFirstLock) {
2739            return isUidForegroundUL(uid);
2740        }
2741    }
2742
2743    private boolean isUidForegroundUL(int uid) {
2744        return isUidStateForegroundUL(
2745                mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY));
2746    }
2747
2748    private boolean isUidForegroundOnRestrictBackgroundUL(int uid) {
2749        final int procState = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
2750        return isProcStateAllowedWhileOnRestrictBackground(procState);
2751    }
2752
2753    private boolean isUidForegroundOnRestrictPowerUL(int uid) {
2754        final int procState = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
2755        return isProcStateAllowedWhileIdleOrPowerSaveMode(procState);
2756    }
2757
2758    private boolean isUidStateForegroundUL(int state) {
2759        // only really in foreground when screen is also on
2760        return state <= ActivityManager.PROCESS_STATE_TOP;
2761    }
2762
2763    /**
2764     * Process state of UID changed; if needed, will trigger
2765     * {@link #updateRulesForDataUsageRestrictionsUL(int)} and
2766     * {@link #updateRulesForPowerRestrictionsUL(int)}
2767     */
2768    private void updateUidStateUL(int uid, int uidState) {
2769        Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateUidStateUL");
2770        try {
2771            final int oldUidState = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
2772            if (oldUidState != uidState) {
2773                // state changed, push updated rules
2774                mUidState.put(uid, uidState);
2775                updateRestrictBackgroundRulesOnUidStatusChangedUL(uid, oldUidState, uidState);
2776                if (isProcStateAllowedWhileIdleOrPowerSaveMode(oldUidState)
2777                        != isProcStateAllowedWhileIdleOrPowerSaveMode(uidState) ) {
2778                    if (isUidIdle(uid)) {
2779                        updateRuleForAppIdleUL(uid);
2780                    }
2781                    if (mDeviceIdleMode) {
2782                        updateRuleForDeviceIdleUL(uid);
2783                    }
2784                    if (mRestrictPower) {
2785                        updateRuleForRestrictPowerUL(uid);
2786                    }
2787                    updateRulesForPowerRestrictionsUL(uid);
2788                }
2789                updateNetworkStats(uid, isUidStateForegroundUL(uidState));
2790            }
2791        } finally {
2792            Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
2793        }
2794    }
2795
2796    private void removeUidStateUL(int uid) {
2797        final int index = mUidState.indexOfKey(uid);
2798        if (index >= 0) {
2799            final int oldUidState = mUidState.valueAt(index);
2800            mUidState.removeAt(index);
2801            if (oldUidState != ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2802                updateRestrictBackgroundRulesOnUidStatusChangedUL(uid, oldUidState,
2803                        ActivityManager.PROCESS_STATE_CACHED_EMPTY);
2804                if (mDeviceIdleMode) {
2805                    updateRuleForDeviceIdleUL(uid);
2806                }
2807                if (mRestrictPower) {
2808                    updateRuleForRestrictPowerUL(uid);
2809                }
2810                updateRulesForPowerRestrictionsUL(uid);
2811                updateNetworkStats(uid, false);
2812            }
2813        }
2814    }
2815
2816    // adjust stats accounting based on foreground status
2817    private void updateNetworkStats(int uid, boolean uidForeground) {
2818        if (Trace.isTagEnabled(Trace.TRACE_TAG_NETWORK)) {
2819            Trace.traceBegin(Trace.TRACE_TAG_NETWORK,
2820                    "updateNetworkStats: " + uid + "/" + (uidForeground ? "F" : "B"));
2821        }
2822        try {
2823            mNetworkStats.setUidForeground(uid, uidForeground);
2824        } catch (RemoteException e) {
2825            // ignored; service lives in system_server
2826        } finally {
2827            Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
2828        }
2829    }
2830
2831    private void updateRestrictBackgroundRulesOnUidStatusChangedUL(int uid, int oldUidState,
2832            int newUidState) {
2833        final boolean oldForeground =
2834                isProcStateAllowedWhileOnRestrictBackground(oldUidState);
2835        final boolean newForeground =
2836                isProcStateAllowedWhileOnRestrictBackground(newUidState);
2837        if (oldForeground != newForeground) {
2838            updateRulesForDataUsageRestrictionsUL(uid);
2839        }
2840    }
2841
2842    void updateRulesForPowerSaveUL() {
2843        Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForPowerSaveUL");
2844        try {
2845            updateRulesForWhitelistedPowerSaveUL(mRestrictPower, FIREWALL_CHAIN_POWERSAVE,
2846                    mUidFirewallPowerSaveRules);
2847        } finally {
2848            Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
2849        }
2850    }
2851
2852    void updateRuleForRestrictPowerUL(int uid) {
2853        updateRulesForWhitelistedPowerSaveUL(uid, mRestrictPower, FIREWALL_CHAIN_POWERSAVE);
2854    }
2855
2856    void updateRulesForDeviceIdleUL() {
2857        Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForDeviceIdleUL");
2858        try {
2859            updateRulesForWhitelistedPowerSaveUL(mDeviceIdleMode, FIREWALL_CHAIN_DOZABLE,
2860                    mUidFirewallDozableRules);
2861        } finally {
2862            Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
2863        }
2864    }
2865
2866    void updateRuleForDeviceIdleUL(int uid) {
2867        updateRulesForWhitelistedPowerSaveUL(uid, mDeviceIdleMode, FIREWALL_CHAIN_DOZABLE);
2868    }
2869
2870    // NOTE: since both fw_dozable and fw_powersave uses the same map
2871    // (mPowerSaveTempWhitelistAppIds) for whitelisting, we can reuse their logic in this method.
2872    private void updateRulesForWhitelistedPowerSaveUL(boolean enabled, int chain,
2873            SparseIntArray rules) {
2874        if (enabled) {
2875            // Sync the whitelists before enabling the chain.  We don't care about the rules if
2876            // we are disabling the chain.
2877            final SparseIntArray uidRules = rules;
2878            uidRules.clear();
2879            final List<UserInfo> users = mUserManager.getUsers();
2880            for (int ui = users.size() - 1; ui >= 0; ui--) {
2881                UserInfo user = users.get(ui);
2882                updateRulesForWhitelistedAppIds(uidRules, mPowerSaveTempWhitelistAppIds, user.id);
2883                updateRulesForWhitelistedAppIds(uidRules, mPowerSaveWhitelistAppIds, user.id);
2884                if (chain == FIREWALL_CHAIN_POWERSAVE) {
2885                    updateRulesForWhitelistedAppIds(uidRules,
2886                            mPowerSaveWhitelistExceptIdleAppIds, user.id);
2887                }
2888            }
2889            for (int i = mUidState.size() - 1; i >= 0; i--) {
2890                if (isProcStateAllowedWhileIdleOrPowerSaveMode(mUidState.valueAt(i))) {
2891                    uidRules.put(mUidState.keyAt(i), FIREWALL_RULE_ALLOW);
2892                }
2893            }
2894            setUidFirewallRulesAsync(chain, uidRules, CHAIN_TOGGLE_ENABLE);
2895        } else {
2896            setUidFirewallRulesAsync(chain, null, CHAIN_TOGGLE_DISABLE);
2897        }
2898    }
2899
2900    private void updateRulesForWhitelistedAppIds(final SparseIntArray uidRules,
2901            final SparseBooleanArray whitelistedAppIds, int userId) {
2902        for (int i = whitelistedAppIds.size() - 1; i >= 0; --i) {
2903            if (whitelistedAppIds.valueAt(i)) {
2904                final int appId = whitelistedAppIds.keyAt(i);
2905                final int uid = UserHandle.getUid(userId, appId);
2906                uidRules.put(uid, FIREWALL_RULE_ALLOW);
2907            }
2908        }
2909    }
2910
2911    /**
2912     * @param deviceIdleMode if true then we don't consider
2913     *        {@link #mPowerSaveWhitelistExceptIdleAppIds} for checking if the {@param uid} is
2914     *        whitelisted.
2915     */
2916    private boolean isWhitelistedBatterySaverUL(int uid, boolean deviceIdleMode) {
2917        final int appId = UserHandle.getAppId(uid);
2918        boolean isWhitelisted = mPowerSaveTempWhitelistAppIds.get(appId)
2919                || mPowerSaveWhitelistAppIds.get(appId);
2920        if (!deviceIdleMode) {
2921            isWhitelisted = isWhitelisted || mPowerSaveWhitelistExceptIdleAppIds.get(appId);
2922        }
2923        return isWhitelisted;
2924    }
2925
2926    // NOTE: since both fw_dozable and fw_powersave uses the same map
2927    // (mPowerSaveTempWhitelistAppIds) for whitelisting, we can reuse their logic in this method.
2928    private void updateRulesForWhitelistedPowerSaveUL(int uid, boolean enabled, int chain) {
2929        if (enabled) {
2930            final boolean isWhitelisted = isWhitelistedBatterySaverUL(uid,
2931                    chain == FIREWALL_CHAIN_DOZABLE);
2932            if (isWhitelisted || isUidForegroundOnRestrictPowerUL(uid)) {
2933                setUidFirewallRule(chain, uid, FIREWALL_RULE_ALLOW);
2934            } else {
2935                setUidFirewallRule(chain, uid, FIREWALL_RULE_DEFAULT);
2936            }
2937        }
2938    }
2939
2940    void updateRulesForAppIdleUL() {
2941        Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForAppIdleUL");
2942        try {
2943            final SparseIntArray uidRules = mUidFirewallStandbyRules;
2944            uidRules.clear();
2945
2946            // Fully update the app idle firewall chain.
2947            final List<UserInfo> users = mUserManager.getUsers();
2948            for (int ui = users.size() - 1; ui >= 0; ui--) {
2949                UserInfo user = users.get(ui);
2950                int[] idleUids = mUsageStats.getIdleUidsForUser(user.id);
2951                for (int uid : idleUids) {
2952                    if (!mPowerSaveTempWhitelistAppIds.get(UserHandle.getAppId(uid), false)) {
2953                        // quick check: if this uid doesn't have INTERNET permission, it
2954                        // doesn't have network access anyway, so it is a waste to mess
2955                        // with it here.
2956                        if (hasInternetPermissions(uid)) {
2957                            uidRules.put(uid, FIREWALL_RULE_DENY);
2958                        }
2959                    }
2960                }
2961            }
2962
2963            setUidFirewallRulesAsync(FIREWALL_CHAIN_STANDBY, uidRules, CHAIN_TOGGLE_NONE);
2964        } finally {
2965            Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
2966        }
2967    }
2968
2969    void updateRuleForAppIdleUL(int uid) {
2970        if (!isUidValidForBlacklistRules(uid)) return;
2971
2972        if (Trace.isTagEnabled(Trace.TRACE_TAG_NETWORK)) {
2973            Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRuleForAppIdleUL: " + uid );
2974        }
2975        try {
2976            int appId = UserHandle.getAppId(uid);
2977            if (!mPowerSaveTempWhitelistAppIds.get(appId) && isUidIdle(uid)
2978                    && !isUidForegroundOnRestrictPowerUL(uid)) {
2979                setUidFirewallRule(FIREWALL_CHAIN_STANDBY, uid, FIREWALL_RULE_DENY);
2980            } else {
2981                setUidFirewallRule(FIREWALL_CHAIN_STANDBY, uid, FIREWALL_RULE_DEFAULT);
2982            }
2983        } finally {
2984            Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
2985        }
2986    }
2987
2988    /**
2989     * Toggle the firewall standby chain and inform listeners if the uid rules have effectively
2990     * changed.
2991     */
2992    void updateRulesForAppIdleParoleUL() {
2993        boolean paroled = mUsageStats.isAppIdleParoleOn();
2994        boolean enableChain = !paroled;
2995        enableFirewallChainUL(FIREWALL_CHAIN_STANDBY, enableChain);
2996
2997        int ruleCount = mUidFirewallStandbyRules.size();
2998        for (int i = 0; i < ruleCount; i++) {
2999            int uid = mUidFirewallStandbyRules.keyAt(i);
3000            int oldRules = mUidRules.get(uid);
3001            if (enableChain) {
3002                // Chain wasn't enabled before and the other power-related
3003                // chains are whitelists, so we can clear the
3004                // MASK_ALL_NETWORKS part of the rules and re-inform listeners if
3005                // the effective rules result in blocking network access.
3006                oldRules &= MASK_METERED_NETWORKS;
3007            } else {
3008                // Skip if it had no restrictions to begin with
3009                if ((oldRules & MASK_ALL_NETWORKS) == 0) continue;
3010            }
3011            final int newUidRules = updateRulesForPowerRestrictionsUL(uid, oldRules, paroled);
3012            if (newUidRules == RULE_NONE) {
3013                mUidRules.delete(uid);
3014            } else {
3015                mUidRules.put(uid, newUidRules);
3016            }
3017        }
3018    }
3019
3020    /**
3021     * Update rules that might be changed by {@link #mRestrictBackground},
3022     * {@link #mRestrictPower}, or {@link #mDeviceIdleMode} value.
3023     */
3024    private void updateRulesForGlobalChangeAL(boolean restrictedNetworksChanged) {
3025        if (Trace.isTagEnabled(Trace.TRACE_TAG_NETWORK)) {
3026            Trace.traceBegin(Trace.TRACE_TAG_NETWORK,
3027                    "updateRulesForGlobalChangeAL: " + (restrictedNetworksChanged ? "R" : "-"));
3028        }
3029        try {
3030            updateRulesForAppIdleUL();
3031            updateRulesForRestrictPowerUL();
3032            updateRulesForRestrictBackgroundUL();
3033
3034            // If the set of restricted networks may have changed, re-evaluate those.
3035            if (restrictedNetworksChanged) {
3036                normalizePoliciesNL();
3037                updateNetworkRulesNL();
3038            }
3039        } finally {
3040            Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
3041        }
3042    }
3043
3044    // TODO: rename / document to make it clear these are global (not app-specific) rules
3045    private void updateRulesForRestrictPowerUL() {
3046        Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForRestrictPowerUL");
3047        try {
3048            updateRulesForDeviceIdleUL();
3049            updateRulesForPowerSaveUL();
3050            updateRulesForAllAppsUL(TYPE_RESTRICT_POWER);
3051        } finally {
3052            Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
3053        }
3054    }
3055
3056    private void updateRulesForRestrictBackgroundUL() {
3057        Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForRestrictBackgroundUL");
3058        try {
3059            updateRulesForAllAppsUL(TYPE_RESTRICT_BACKGROUND);
3060        } finally {
3061            Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
3062        }
3063    }
3064
3065    private static final int TYPE_RESTRICT_BACKGROUND = 1;
3066    private static final int TYPE_RESTRICT_POWER = 2;
3067    @Retention(RetentionPolicy.SOURCE)
3068    @IntDef(flag = false, value = {
3069            TYPE_RESTRICT_BACKGROUND,
3070            TYPE_RESTRICT_POWER,
3071    })
3072    public @interface RestrictType {
3073    }
3074
3075    // TODO: refactor / consolidate all those updateXyz methods, there are way too many of them...
3076    private void updateRulesForAllAppsUL(@RestrictType int type) {
3077        if (Trace.isTagEnabled(Trace.TRACE_TAG_NETWORK)) {
3078            Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForRestrictPowerUL-" + type);
3079        }
3080        try {
3081            // update rules for all installed applications
3082
3083            final PackageManager pm = mContext.getPackageManager();
3084            final List<UserInfo> users;
3085            final List<ApplicationInfo> apps;
3086
3087            Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "list-users");
3088            try {
3089                users = mUserManager.getUsers();
3090            } finally {
3091                Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
3092            }
3093            Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "list-uids");
3094            try {
3095                apps = pm.getInstalledApplications(
3096                        PackageManager.MATCH_ANY_USER | PackageManager.MATCH_DISABLED_COMPONENTS
3097                                | PackageManager.MATCH_DIRECT_BOOT_AWARE
3098                                | PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
3099            } finally {
3100                Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
3101            }
3102
3103            final int usersSize = users.size();
3104            final int appsSize = apps.size();
3105            for (int i = 0; i < usersSize; i++) {
3106                final UserInfo user = users.get(i);
3107                for (int j = 0; j < appsSize; j++) {
3108                    final ApplicationInfo app = apps.get(j);
3109                    final int uid = UserHandle.getUid(user.id, app.uid);
3110                    switch (type) {
3111                        case TYPE_RESTRICT_BACKGROUND:
3112                            updateRulesForDataUsageRestrictionsUL(uid);
3113                            break;
3114                        case TYPE_RESTRICT_POWER:
3115                            updateRulesForPowerRestrictionsUL(uid);
3116                            break;
3117                        default:
3118                            Slog.w(TAG, "Invalid type for updateRulesForAllApps: " + type);
3119                    }
3120                }
3121            }
3122        } finally {
3123            Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
3124        }
3125    }
3126
3127    private void updateRulesForTempWhitelistChangeUL() {
3128        final List<UserInfo> users = mUserManager.getUsers();
3129        for (int i = 0; i < users.size(); i++) {
3130            final UserInfo user = users.get(i);
3131            for (int j = mPowerSaveTempWhitelistAppIds.size() - 1; j >= 0; j--) {
3132                int appId = mPowerSaveTempWhitelistAppIds.keyAt(j);
3133                int uid = UserHandle.getUid(user.id, appId);
3134                // Update external firewall rules.
3135                updateRuleForAppIdleUL(uid);
3136                updateRuleForDeviceIdleUL(uid);
3137                updateRuleForRestrictPowerUL(uid);
3138                // Update internal rules.
3139                updateRulesForPowerRestrictionsUL(uid);
3140            }
3141        }
3142    }
3143
3144    // TODO: the MEDIA / DRM restriction might not be needed anymore, in which case both
3145    // methods below could be merged into a isUidValidForRules() method.
3146    private boolean isUidValidForBlacklistRules(int uid) {
3147        // allow rules on specific system services, and any apps
3148        if (uid == android.os.Process.MEDIA_UID || uid == android.os.Process.DRM_UID
3149            || (UserHandle.isApp(uid) && hasInternetPermissions(uid))) {
3150            return true;
3151        }
3152
3153        return false;
3154    }
3155
3156    private boolean isUidValidForWhitelistRules(int uid) {
3157        return UserHandle.isApp(uid) && hasInternetPermissions(uid);
3158    }
3159
3160    private boolean isUidIdle(int uid) {
3161        final String[] packages = mContext.getPackageManager().getPackagesForUid(uid);
3162        final int userId = UserHandle.getUserId(uid);
3163
3164        if (packages != null) {
3165            for (String packageName : packages) {
3166                if (!mUsageStats.isAppIdle(packageName, uid, userId)) {
3167                    return false;
3168                }
3169            }
3170        }
3171        return true;
3172    }
3173
3174    /**
3175     * Checks if an uid has INTERNET permissions.
3176     * <p>
3177     * Useful for the cases where the lack of network access can simplify the rules.
3178     */
3179    private boolean hasInternetPermissions(int uid) {
3180        try {
3181            if (mIPm.checkUidPermission(Manifest.permission.INTERNET, uid)
3182                    != PackageManager.PERMISSION_GRANTED) {
3183                return false;
3184            }
3185        } catch (RemoteException e) {
3186        }
3187        return true;
3188    }
3189
3190    /**
3191     * Clears all state - internal and external - associated with an UID.
3192     */
3193    private void onUidDeletedUL(int uid) {
3194        // First cleanup in-memory state synchronously...
3195        mUidRules.delete(uid);
3196        mUidPolicy.delete(uid);
3197        mUidFirewallStandbyRules.delete(uid);
3198        mUidFirewallDozableRules.delete(uid);
3199        mUidFirewallPowerSaveRules.delete(uid);
3200        mPowerSaveWhitelistExceptIdleAppIds.delete(uid);
3201        mPowerSaveWhitelistAppIds.delete(uid);
3202        mPowerSaveTempWhitelistAppIds.delete(uid);
3203
3204        // ...then update iptables asynchronously.
3205        mHandler.obtainMessage(MSG_RESET_FIREWALL_RULES_BY_UID, uid, 0).sendToTarget();
3206    }
3207
3208    /**
3209     * Applies network rules to bandwidth and firewall controllers based on uid policy.
3210     *
3211     * <p>There are currently 4 types of restriction rules:
3212     * <ul>
3213     * <li>Doze mode
3214     * <li>App idle mode
3215     * <li>Battery Saver Mode (also referred as power save).
3216     * <li>Data Saver Mode (The Feature Formerly Known As 'Restrict Background Data').
3217     * </ul>
3218     *
3219     * <p>This method changes both the external firewall rules and the internal state.
3220     */
3221    private void updateRestrictionRulesForUidUL(int uid) {
3222        // Methods below only changes the firewall rules for the power-related modes.
3223        updateRuleForDeviceIdleUL(uid);
3224        updateRuleForAppIdleUL(uid);
3225        updateRuleForRestrictPowerUL(uid);
3226
3227        // Update internal state for power-related modes.
3228        updateRulesForPowerRestrictionsUL(uid);
3229
3230        // Update firewall and internal rules for Data Saver Mode.
3231        updateRulesForDataUsageRestrictionsUL(uid);
3232    }
3233
3234    /**
3235     * Applies network rules to bandwidth controllers based on process state and user-defined
3236     * restrictions (blacklist / whitelist).
3237     *
3238     * <p>
3239     * {@code netd} defines 3 firewall chains that govern whether an app has access to metered
3240     * networks:
3241     * <ul>
3242     * <li>@{code bw_penalty_box}: UIDs added to this chain do not have access (blacklist).
3243     * <li>@{code bw_happy_box}: UIDs added to this chain have access (whitelist), unless they're
3244     *     also blacklisted.
3245     * <li>@{code bw_data_saver}: when enabled (through {@link #setRestrictBackground(boolean)}),
3246     *     no UIDs other those whitelisted will have access.
3247     * <ul>
3248     *
3249     * <p>The @{code bw_penalty_box} and @{code bw_happy_box} are primarily managed through the
3250     * {@link #setUidPolicy(int, int)} and {@link #addRestrictBackgroundWhitelistedUid(int)} /
3251     * {@link #removeRestrictBackgroundWhitelistedUid(int)} methods (for blacklist and whitelist
3252     * respectively): these methods set the proper internal state (blacklist / whitelist), then call
3253     * this ({@link #updateRulesForDataUsageRestrictionsUL(int)}) to propagate the rules to
3254     * {@link INetworkManagementService}, but this method should also be called in events (like
3255     * Data Saver Mode flips or UID state changes) that might affect the foreground app, since the
3256     * following rules should also be applied:
3257     *
3258     * <ul>
3259     * <li>When Data Saver mode is on, the foreground app should be temporarily added to
3260     *     {@code bw_happy_box} before the @{code bw_data_saver} chain is enabled.
3261     * <li>If the foreground app is blacklisted by the user, it should be temporarily removed from
3262     *     {@code bw_penalty_box}.
3263     * <li>When the app leaves foreground state, the temporary changes above should be reverted.
3264     * </ul>
3265     *
3266     * <p>For optimization, the rules are only applied on user apps that have internet access
3267     * permission, since there is no need to change the {@code iptables} rule if the app does not
3268     * have permission to use the internet.
3269     *
3270     * <p>The {@link #mUidRules} map is used to define the transtion of states of an UID.
3271     *
3272     */
3273    private void updateRulesForDataUsageRestrictionsUL(int uid) {
3274        if (Trace.isTagEnabled(Trace.TRACE_TAG_NETWORK)) {
3275            Trace.traceBegin(Trace.TRACE_TAG_NETWORK,
3276                    "updateRulesForDataUsageRestrictionsUL: " + uid);
3277        }
3278        try {
3279            updateRulesForDataUsageRestrictionsULInner(uid);
3280        } finally {
3281            Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
3282        }
3283    }
3284
3285    private void updateRulesForDataUsageRestrictionsULInner(int uid) {
3286        if (!isUidValidForWhitelistRules(uid)) {
3287            if (LOGD) Slog.d(TAG, "no need to update restrict data rules for uid " + uid);
3288            return;
3289        }
3290
3291        final int uidPolicy = mUidPolicy.get(uid, POLICY_NONE);
3292        final int oldUidRules = mUidRules.get(uid, RULE_NONE);
3293        final boolean isForeground = isUidForegroundOnRestrictBackgroundUL(uid);
3294
3295        final boolean isBlacklisted = (uidPolicy & POLICY_REJECT_METERED_BACKGROUND) != 0;
3296        final boolean isWhitelisted = (uidPolicy & POLICY_ALLOW_METERED_BACKGROUND) != 0;
3297        final int oldRule = oldUidRules & MASK_METERED_NETWORKS;
3298        int newRule = RULE_NONE;
3299
3300        // First step: define the new rule based on user restrictions and foreground state.
3301        if (isForeground) {
3302            if (isBlacklisted || (mRestrictBackground && !isWhitelisted)) {
3303                newRule = RULE_TEMPORARY_ALLOW_METERED;
3304            } else if (isWhitelisted) {
3305                newRule = RULE_ALLOW_METERED;
3306            }
3307        } else {
3308            if (isBlacklisted) {
3309                newRule = RULE_REJECT_METERED;
3310            } else if (mRestrictBackground && isWhitelisted) {
3311                newRule = RULE_ALLOW_METERED;
3312            }
3313        }
3314        final int newUidRules = newRule | (oldUidRules & MASK_ALL_NETWORKS);
3315
3316        if (LOGV) {
3317            Log.v(TAG, "updateRuleForRestrictBackgroundUL(" + uid + ")"
3318                    + ": isForeground=" +isForeground
3319                    + ", isBlacklisted=" + isBlacklisted
3320                    + ", isWhitelisted=" + isWhitelisted
3321                    + ", oldRule=" + uidRulesToString(oldRule)
3322                    + ", newRule=" + uidRulesToString(newRule)
3323                    + ", newUidRules=" + uidRulesToString(newUidRules)
3324                    + ", oldUidRules=" + uidRulesToString(oldUidRules));
3325        }
3326
3327        if (newUidRules == RULE_NONE) {
3328            mUidRules.delete(uid);
3329        } else {
3330            mUidRules.put(uid, newUidRules);
3331        }
3332
3333        // Second step: apply bw changes based on change of state.
3334        if (newRule != oldRule) {
3335            if ((newRule & RULE_TEMPORARY_ALLOW_METERED) != 0) {
3336                // Temporarily whitelist foreground app, removing from blacklist if necessary
3337                // (since bw_penalty_box prevails over bw_happy_box).
3338
3339                setMeteredNetworkWhitelist(uid, true);
3340                // TODO: if statement below is used to avoid an unnecessary call to netd / iptables,
3341                // but ideally it should be just:
3342                //    setMeteredNetworkBlacklist(uid, isBlacklisted);
3343                if (isBlacklisted) {
3344                    setMeteredNetworkBlacklist(uid, false);
3345                }
3346            } else if ((oldRule & RULE_TEMPORARY_ALLOW_METERED) != 0) {
3347                // Remove temporary whitelist from app that is not on foreground anymore.
3348
3349                // TODO: if statements below are used to avoid unnecessary calls to netd / iptables,
3350                // but ideally they should be just:
3351                //    setMeteredNetworkWhitelist(uid, isWhitelisted);
3352                //    setMeteredNetworkBlacklist(uid, isBlacklisted);
3353                if (!isWhitelisted) {
3354                    setMeteredNetworkWhitelist(uid, false);
3355                }
3356                if (isBlacklisted) {
3357                    setMeteredNetworkBlacklist(uid, true);
3358                }
3359            } else if ((newRule & RULE_REJECT_METERED) != 0
3360                    || (oldRule & RULE_REJECT_METERED) != 0) {
3361                // Flip state because app was explicitly added or removed to blacklist.
3362                setMeteredNetworkBlacklist(uid, isBlacklisted);
3363                if ((oldRule & RULE_REJECT_METERED) != 0 && isWhitelisted) {
3364                    // Since blacklist prevails over whitelist, we need to handle the special case
3365                    // where app is whitelisted and blacklisted at the same time (although such
3366                    // scenario should be blocked by the UI), then blacklist is removed.
3367                    setMeteredNetworkWhitelist(uid, isWhitelisted);
3368                }
3369            } else if ((newRule & RULE_ALLOW_METERED) != 0
3370                    || (oldRule & RULE_ALLOW_METERED) != 0) {
3371                // Flip state because app was explicitly added or removed to whitelist.
3372                setMeteredNetworkWhitelist(uid, isWhitelisted);
3373            } else {
3374                // All scenarios should have been covered above.
3375                Log.wtf(TAG, "Unexpected change of metered UID state for " + uid
3376                        + ": foreground=" + isForeground
3377                        + ", whitelisted=" + isWhitelisted
3378                        + ", blacklisted=" + isBlacklisted
3379                        + ", newRule=" + uidRulesToString(newUidRules)
3380                        + ", oldRule=" + uidRulesToString(oldUidRules));
3381            }
3382
3383            // Dispatch changed rule to existing listeners.
3384            mHandler.obtainMessage(MSG_RULES_CHANGED, uid, newUidRules).sendToTarget();
3385        }
3386    }
3387
3388    /**
3389     * Updates the power-related part of the {@link #mUidRules} for a given map, and notify external
3390     * listeners in case of change.
3391     * <p>
3392     * There are 3 power-related rules that affects whether an app has background access on
3393     * non-metered networks, and when the condition applies and the UID is not whitelisted for power
3394     * restriction, it's added to the equivalent firewall chain:
3395     * <ul>
3396     * <li>App is idle: {@code fw_standby} firewall chain.
3397     * <li>Device is idle: {@code fw_dozable} firewall chain.
3398     * <li>Battery Saver Mode is on: {@code fw_powersave} firewall chain.
3399     * </ul>
3400     * <p>
3401     * This method updates the power-related part of the {@link #mUidRules} for a given uid based on
3402     * these modes, the UID process state (foreground or not), and the UIDwhitelist state.
3403     * <p>
3404     * <strong>NOTE: </strong>This method does not update the firewall rules on {@code netd}.
3405     */
3406    private void updateRulesForPowerRestrictionsUL(int uid) {
3407        final int oldUidRules = mUidRules.get(uid, RULE_NONE);
3408
3409        final int newUidRules = updateRulesForPowerRestrictionsUL(uid, oldUidRules, false);
3410
3411        if (newUidRules == RULE_NONE) {
3412            mUidRules.delete(uid);
3413        } else {
3414            mUidRules.put(uid, newUidRules);
3415        }
3416    }
3417
3418    /**
3419     * Similar to above but ignores idle state if app standby is currently disabled by parole.
3420     *
3421     * @param uid the uid of the app to update rules for
3422     * @param oldUidRules the current rules for the uid, in order to determine if there's a change
3423     * @param paroled whether to ignore idle state of apps and only look at other restrictions.
3424     *
3425     * @return the new computed rules for the uid
3426     */
3427    private int updateRulesForPowerRestrictionsUL(int uid, int oldUidRules, boolean paroled) {
3428        if (Trace.isTagEnabled(Trace.TRACE_TAG_NETWORK)) {
3429            Trace.traceBegin(Trace.TRACE_TAG_NETWORK,
3430                    "updateRulesForPowerRestrictionsUL: " + uid + "/" + oldUidRules + "/"
3431                    + (paroled ? "P" : "-"));
3432        }
3433        try {
3434            return updateRulesForPowerRestrictionsULInner(uid, oldUidRules, paroled);
3435        } finally {
3436            Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
3437        }
3438    }
3439
3440    private int updateRulesForPowerRestrictionsULInner(int uid, int oldUidRules, boolean paroled) {
3441        if (!isUidValidForBlacklistRules(uid)) {
3442            if (LOGD) Slog.d(TAG, "no need to update restrict power rules for uid " + uid);
3443            return RULE_NONE;
3444        }
3445
3446        final boolean isIdle = !paroled && isUidIdle(uid);
3447        final boolean restrictMode = isIdle || mRestrictPower || mDeviceIdleMode;
3448        final boolean isForeground = isUidForegroundOnRestrictPowerUL(uid);
3449
3450        final boolean isWhitelisted = isWhitelistedBatterySaverUL(uid, mDeviceIdleMode);
3451        final int oldRule = oldUidRules & MASK_ALL_NETWORKS;
3452        int newRule = RULE_NONE;
3453
3454        // First step: define the new rule based on user restrictions and foreground state.
3455
3456        // NOTE: if statements below could be inlined, but it's easier to understand the logic
3457        // by considering the foreground and non-foreground states.
3458        if (isForeground) {
3459            if (restrictMode) {
3460                newRule = RULE_ALLOW_ALL;
3461            }
3462        } else if (restrictMode) {
3463            newRule = isWhitelisted ? RULE_ALLOW_ALL : RULE_REJECT_ALL;
3464        }
3465
3466        final int newUidRules = (oldUidRules & MASK_METERED_NETWORKS) | newRule;
3467
3468        if (LOGV) {
3469            Log.v(TAG, "updateRulesForPowerRestrictionsUL(" + uid + ")"
3470                    + ", isIdle: " + isIdle
3471                    + ", mRestrictPower: " + mRestrictPower
3472                    + ", mDeviceIdleMode: " + mDeviceIdleMode
3473                    + ", isForeground=" + isForeground
3474                    + ", isWhitelisted=" + isWhitelisted
3475                    + ", oldRule=" + uidRulesToString(oldRule)
3476                    + ", newRule=" + uidRulesToString(newRule)
3477                    + ", newUidRules=" + uidRulesToString(newUidRules)
3478                    + ", oldUidRules=" + uidRulesToString(oldUidRules));
3479        }
3480
3481        // Second step: notify listeners if state changed.
3482        if (newRule != oldRule) {
3483            if (newRule == RULE_NONE || (newRule & RULE_ALLOW_ALL) != 0) {
3484                if (LOGV) Log.v(TAG, "Allowing non-metered access for UID " + uid);
3485            } else if ((newRule & RULE_REJECT_ALL) != 0) {
3486                if (LOGV) Log.v(TAG, "Rejecting non-metered access for UID " + uid);
3487            } else {
3488                // All scenarios should have been covered above
3489                Log.wtf(TAG, "Unexpected change of non-metered UID state for " + uid
3490                        + ": foreground=" + isForeground
3491                        + ", whitelisted=" + isWhitelisted
3492                        + ", newRule=" + uidRulesToString(newUidRules)
3493                        + ", oldRule=" + uidRulesToString(oldUidRules));
3494            }
3495            mHandler.obtainMessage(MSG_RULES_CHANGED, uid, newUidRules).sendToTarget();
3496        }
3497
3498        return newUidRules;
3499    }
3500
3501    private class AppIdleStateChangeListener
3502            extends UsageStatsManagerInternal.AppIdleStateChangeListener {
3503
3504        @Override
3505        public void onAppIdleStateChanged(String packageName, int userId, boolean idle) {
3506            try {
3507                final int uid = mContext.getPackageManager().getPackageUidAsUser(packageName,
3508                        PackageManager.MATCH_UNINSTALLED_PACKAGES, userId);
3509                if (LOGV) Log.v(TAG, "onAppIdleStateChanged(): uid=" + uid + ", idle=" + idle);
3510                synchronized (mUidRulesFirstLock) {
3511                    updateRuleForAppIdleUL(uid);
3512                    updateRulesForPowerRestrictionsUL(uid);
3513                }
3514            } catch (NameNotFoundException nnfe) {
3515            }
3516        }
3517
3518        @Override
3519        public void onParoleStateChanged(boolean isParoleOn) {
3520            synchronized (mUidRulesFirstLock) {
3521                updateRulesForAppIdleParoleUL();
3522            }
3523        }
3524    }
3525
3526    private void dispatchUidRulesChanged(INetworkPolicyListener listener, int uid, int uidRules) {
3527        if (listener != null) {
3528            try {
3529                listener.onUidRulesChanged(uid, uidRules);
3530            } catch (RemoteException ignored) {
3531            }
3532        }
3533    }
3534
3535    private void dispatchMeteredIfacesChanged(INetworkPolicyListener listener,
3536            String[] meteredIfaces) {
3537        if (listener != null) {
3538            try {
3539                listener.onMeteredIfacesChanged(meteredIfaces);
3540            } catch (RemoteException ignored) {
3541            }
3542        }
3543    }
3544
3545    private void dispatchRestrictBackgroundChanged(INetworkPolicyListener listener,
3546            boolean restrictBackground) {
3547        if (listener != null) {
3548            try {
3549                listener.onRestrictBackgroundChanged(restrictBackground);
3550            } catch (RemoteException ignored) {
3551            }
3552        }
3553    }
3554
3555    private void dispatchUidPoliciesChanged(INetworkPolicyListener listener, int uid,
3556            int uidPolicies) {
3557        if (listener != null) {
3558            try {
3559                listener.onUidPoliciesChanged(uid, uidPolicies);
3560            } catch (RemoteException ignored) {
3561            }
3562        }
3563    }
3564
3565    private final Handler.Callback mHandlerCallback = new Handler.Callback() {
3566        @Override
3567        public boolean handleMessage(Message msg) {
3568            switch (msg.what) {
3569                case MSG_RULES_CHANGED: {
3570                    final int uid = msg.arg1;
3571                    final int uidRules = msg.arg2;
3572                    final int length = mListeners.beginBroadcast();
3573                    for (int i = 0; i < length; i++) {
3574                        final INetworkPolicyListener listener = mListeners.getBroadcastItem(i);
3575                        dispatchUidRulesChanged(listener, uid, uidRules);
3576                    }
3577                    mListeners.finishBroadcast();
3578                    return true;
3579                }
3580                case MSG_METERED_IFACES_CHANGED: {
3581                    final String[] meteredIfaces = (String[]) msg.obj;
3582                    final int length = mListeners.beginBroadcast();
3583                    for (int i = 0; i < length; i++) {
3584                        final INetworkPolicyListener listener = mListeners.getBroadcastItem(i);
3585                        dispatchMeteredIfacesChanged(listener, meteredIfaces);
3586                    }
3587                    mListeners.finishBroadcast();
3588                    return true;
3589                }
3590                case MSG_LIMIT_REACHED: {
3591                    final String iface = (String) msg.obj;
3592
3593                    maybeRefreshTrustedTime();
3594                    synchronized (mNetworkPoliciesSecondLock) {
3595                        if (mMeteredIfaces.contains(iface)) {
3596                            try {
3597                                // force stats update to make sure we have
3598                                // numbers that caused alert to trigger.
3599                                mNetworkStats.forceUpdate();
3600                            } catch (RemoteException e) {
3601                                // ignored; service lives in system_server
3602                            }
3603
3604                            updateNetworkEnabledNL();
3605                            updateNotificationsNL();
3606                        }
3607                    }
3608                    return true;
3609                }
3610                case MSG_RESTRICT_BACKGROUND_CHANGED: {
3611                    final boolean restrictBackground = msg.arg1 != 0;
3612                    final int length = mListeners.beginBroadcast();
3613                    for (int i = 0; i < length; i++) {
3614                        final INetworkPolicyListener listener = mListeners.getBroadcastItem(i);
3615                        dispatchRestrictBackgroundChanged(listener, restrictBackground);
3616                    }
3617                    mListeners.finishBroadcast();
3618                    final Intent intent =
3619                            new Intent(ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED);
3620                    intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3621                    mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
3622                    return true;
3623                }
3624                case MSG_POLICIES_CHANGED: {
3625                    final int uid = msg.arg1;
3626                    final int policy = msg.arg2;
3627                    final Boolean notifyApp = (Boolean) msg.obj;
3628                    // First notify internal listeners...
3629                    final int length = mListeners.beginBroadcast();
3630                    for (int i = 0; i < length; i++) {
3631                        final INetworkPolicyListener listener = mListeners.getBroadcastItem(i);
3632                        dispatchUidPoliciesChanged(listener, uid, policy);
3633                    }
3634                    mListeners.finishBroadcast();
3635                    // ...then apps listening to ACTION_RESTRICT_BACKGROUND_CHANGED
3636                    if (notifyApp.booleanValue()) {
3637                        broadcastRestrictBackgroundChanged(uid, notifyApp);
3638                    }
3639                    return true;
3640                }
3641                case MSG_ADVISE_PERSIST_THRESHOLD: {
3642                    final long lowestRule = (Long) msg.obj;
3643                    try {
3644                        // make sure stats are recorded frequently enough; we aim
3645                        // for 2MB threshold for 2GB/month rules.
3646                        final long persistThreshold = lowestRule / 1000;
3647                        mNetworkStats.advisePersistThreshold(persistThreshold);
3648                    } catch (RemoteException e) {
3649                        // ignored; service lives in system_server
3650                    }
3651                    return true;
3652                }
3653                case MSG_UPDATE_INTERFACE_QUOTA: {
3654                    removeInterfaceQuota((String) msg.obj);
3655                    // int params need to be stitched back into a long
3656                    setInterfaceQuota((String) msg.obj,
3657                            ((long) msg.arg1 << 32) | (msg.arg2 & 0xFFFFFFFFL));
3658                    return true;
3659                }
3660                case MSG_REMOVE_INTERFACE_QUOTA: {
3661                    removeInterfaceQuota((String) msg.obj);
3662                    return true;
3663                }
3664                case MSG_SET_FIREWALL_RULES: {
3665                    final int chain = msg.arg1;
3666                    final int toggle = msg.arg2;
3667                    final SparseIntArray uidRules = (SparseIntArray) msg.obj;
3668                    if (uidRules != null) {
3669                        setUidFirewallRules(chain, uidRules);
3670                    }
3671                    if (toggle != CHAIN_TOGGLE_NONE) {
3672                        enableFirewallChainUL(chain, toggle == CHAIN_TOGGLE_ENABLE);
3673                    }
3674                    return true;
3675                }
3676                case MSG_RESET_FIREWALL_RULES_BY_UID: {
3677                    resetUidFirewallRules(msg.arg1);
3678                    return true;
3679                }
3680                default: {
3681                    return false;
3682                }
3683            }
3684        }
3685    };
3686
3687    private final Handler.Callback mUidEventHandlerCallback = new Handler.Callback() {
3688        @Override
3689        public boolean handleMessage(Message msg) {
3690            switch (msg.what) {
3691                case UID_MSG_STATE_CHANGED: {
3692                    final int uid = msg.arg1;
3693                    final int procState = msg.arg2;
3694                    final long procStateSeq = (Long) msg.obj;
3695
3696                    handleUidChanged(uid, procState, procStateSeq);
3697                    return true;
3698                }
3699                case UID_MSG_GONE: {
3700                    final int uid = msg.arg1;
3701                    handleUidGone(uid);
3702                    return true;
3703                }
3704                default: {
3705                    return false;
3706                }
3707            }
3708        }
3709
3710    };
3711
3712    void handleUidChanged(int uid, int procState, long procStateSeq) {
3713        Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "onUidStateChanged");
3714        try {
3715            synchronized (mUidRulesFirstLock) {
3716                // We received a uid state change callback, add it to the history so that it
3717                // will be useful for debugging.
3718                mObservedHistory.addProcStateSeqUL(uid, procStateSeq);
3719                // Now update the network policy rules as per the updated uid state.
3720                updateUidStateUL(uid, procState);
3721                // Updating the network rules is done, so notify AMS about this.
3722                mActivityManagerInternal.notifyNetworkPolicyRulesUpdated(uid, procStateSeq);
3723            }
3724        } finally {
3725            Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
3726        }
3727    }
3728
3729    void handleUidGone(int uid) {
3730        Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "onUidGone");
3731        try {
3732            synchronized (mUidRulesFirstLock) {
3733                removeUidStateUL(uid);
3734            }
3735        } finally {
3736            Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
3737        }
3738    }
3739
3740    private void broadcastRestrictBackgroundChanged(int uid, Boolean changed) {
3741        final PackageManager pm = mContext.getPackageManager();
3742        final String[] packages = pm.getPackagesForUid(uid);
3743        if (packages != null) {
3744            final int userId = UserHandle.getUserId(uid);
3745            for (String packageName : packages) {
3746                final Intent intent =
3747                        new Intent(ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED);
3748                intent.setPackage(packageName);
3749                intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3750                mContext.sendBroadcastAsUser(intent, UserHandle.of(userId));
3751            }
3752        }
3753    }
3754
3755    private void setInterfaceQuota(String iface, long quotaBytes) {
3756        try {
3757            mNetworkManager.setInterfaceQuota(iface, quotaBytes);
3758        } catch (IllegalStateException e) {
3759            Log.wtf(TAG, "problem setting interface quota", e);
3760        } catch (RemoteException e) {
3761            // ignored; service lives in system_server
3762        }
3763    }
3764
3765    private void removeInterfaceQuota(String iface) {
3766        try {
3767            mNetworkManager.removeInterfaceQuota(iface);
3768        } catch (IllegalStateException e) {
3769            Log.wtf(TAG, "problem removing interface quota", e);
3770        } catch (RemoteException e) {
3771            // ignored; service lives in system_server
3772        }
3773    }
3774
3775    private void setMeteredNetworkBlacklist(int uid, boolean enable) {
3776        if (LOGV) Slog.v(TAG, "setMeteredNetworkBlacklist " + uid + ": " + enable);
3777        try {
3778            mNetworkManager.setUidMeteredNetworkBlacklist(uid, enable);
3779        } catch (IllegalStateException e) {
3780            Log.wtf(TAG, "problem setting blacklist (" + enable + ") rules for " + uid, e);
3781        } catch (RemoteException e) {
3782            // ignored; service lives in system_server
3783        }
3784    }
3785
3786    private void setMeteredNetworkWhitelist(int uid, boolean enable) {
3787        if (LOGV) Slog.v(TAG, "setMeteredNetworkWhitelist " + uid + ": " + enable);
3788        try {
3789            mNetworkManager.setUidMeteredNetworkWhitelist(uid, enable);
3790        } catch (IllegalStateException e) {
3791            Log.wtf(TAG, "problem setting whitelist (" + enable + ") rules for " + uid, e);
3792        } catch (RemoteException e) {
3793            // ignored; service lives in system_server
3794        }
3795    }
3796
3797    private static final int CHAIN_TOGGLE_NONE = 0;
3798    private static final int CHAIN_TOGGLE_ENABLE = 1;
3799    private static final int CHAIN_TOGGLE_DISABLE = 2;
3800    @Retention(RetentionPolicy.SOURCE)
3801    @IntDef(flag = false, value = {
3802            CHAIN_TOGGLE_NONE,
3803            CHAIN_TOGGLE_ENABLE,
3804            CHAIN_TOGGLE_DISABLE
3805    })
3806    public @interface ChainToggleType {
3807    }
3808
3809    /**
3810     * Calls {@link #setUidFirewallRules(int, SparseIntArray)} and
3811     * {@link #enableFirewallChainUL(int, boolean)} asynchronously.
3812     *
3813     * @param chain firewall chain.
3814     * @param uidRules new UID rules; if {@code null}, only toggles chain state.
3815     * @param toggle whether the chain should be enabled, disabled, or not changed.
3816     */
3817    private void setUidFirewallRulesAsync(int chain, @Nullable SparseIntArray uidRules,
3818            @ChainToggleType int toggle) {
3819        mHandler.obtainMessage(MSG_SET_FIREWALL_RULES, chain, toggle, uidRules).sendToTarget();
3820    }
3821
3822    /**
3823     * Set uid rules on a particular firewall chain. This is going to synchronize the rules given
3824     * here to netd.  It will clean up dead rules and make sure the target chain only contains rules
3825     * specified here.
3826     */
3827    private void setUidFirewallRules(int chain, SparseIntArray uidRules) {
3828        try {
3829            int size = uidRules.size();
3830            int[] uids = new int[size];
3831            int[] rules = new int[size];
3832            for(int index = size - 1; index >= 0; --index) {
3833                uids[index] = uidRules.keyAt(index);
3834                rules[index] = uidRules.valueAt(index);
3835            }
3836            mNetworkManager.setFirewallUidRules(chain, uids, rules);
3837        } catch (IllegalStateException e) {
3838            Log.wtf(TAG, "problem setting firewall uid rules", e);
3839        } catch (RemoteException e) {
3840            // ignored; service lives in system_server
3841        }
3842    }
3843
3844    /**
3845     * Add or remove a uid to the firewall blacklist for all network ifaces.
3846     */
3847    private void setUidFirewallRule(int chain, int uid, int rule) {
3848        if (Trace.isTagEnabled(Trace.TRACE_TAG_NETWORK)) {
3849            Trace.traceBegin(Trace.TRACE_TAG_NETWORK,
3850                    "setUidFirewallRule: " + chain + "/" + uid + "/" + rule);
3851        }
3852        try {
3853            if (chain == FIREWALL_CHAIN_DOZABLE) {
3854                mUidFirewallDozableRules.put(uid, rule);
3855            } else if (chain == FIREWALL_CHAIN_STANDBY) {
3856                mUidFirewallStandbyRules.put(uid, rule);
3857            } else if (chain == FIREWALL_CHAIN_POWERSAVE) {
3858                mUidFirewallPowerSaveRules.put(uid, rule);
3859            }
3860
3861            try {
3862                mNetworkManager.setFirewallUidRule(chain, uid, rule);
3863            } catch (IllegalStateException e) {
3864                Log.wtf(TAG, "problem setting firewall uid rules", e);
3865            } catch (RemoteException e) {
3866                // ignored; service lives in system_server
3867            }
3868        } finally {
3869            Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
3870        }
3871    }
3872
3873    /**
3874     * Add or remove a uid to the firewall blacklist for all network ifaces.
3875     */
3876    private void enableFirewallChainUL(int chain, boolean enable) {
3877        if (mFirewallChainStates.indexOfKey(chain) >= 0 &&
3878                mFirewallChainStates.get(chain) == enable) {
3879            // All is the same, nothing to do.
3880            return;
3881        }
3882        mFirewallChainStates.put(chain, enable);
3883        try {
3884            mNetworkManager.setFirewallChainEnabled(chain, enable);
3885        } catch (IllegalStateException e) {
3886            Log.wtf(TAG, "problem enable firewall chain", e);
3887        } catch (RemoteException e) {
3888            // ignored; service lives in system_server
3889        }
3890    }
3891
3892    /**
3893     * Resets all firewall rules associated with an UID.
3894     */
3895    private void resetUidFirewallRules(int uid) {
3896        try {
3897            mNetworkManager.setFirewallUidRule(FIREWALL_CHAIN_DOZABLE, uid, FIREWALL_RULE_DEFAULT);
3898            mNetworkManager.setFirewallUidRule(FIREWALL_CHAIN_STANDBY, uid, FIREWALL_RULE_DEFAULT);
3899            mNetworkManager
3900                    .setFirewallUidRule(FIREWALL_CHAIN_POWERSAVE, uid, FIREWALL_RULE_DEFAULT);
3901            mNetworkManager.setUidMeteredNetworkWhitelist(uid, false);
3902            mNetworkManager.setUidMeteredNetworkBlacklist(uid, false);
3903        } catch (IllegalStateException e) {
3904            Log.wtf(TAG, "problem resetting firewall uid rules for " + uid, e);
3905        } catch (RemoteException e) {
3906            // ignored; service lives in system_server
3907        }
3908    }
3909
3910    private long getTotalBytes(NetworkTemplate template, long start, long end) {
3911        try {
3912            return mNetworkStats.getNetworkTotalBytes(template, start, end);
3913        } catch (RuntimeException e) {
3914            Slog.w(TAG, "problem reading network stats: " + e);
3915            return 0;
3916        } catch (RemoteException e) {
3917            // ignored; service lives in system_server
3918            return 0;
3919        }
3920    }
3921
3922    private boolean isBandwidthControlEnabled() {
3923        final long token = Binder.clearCallingIdentity();
3924        try {
3925            return mNetworkManager.isBandwidthControlEnabled();
3926        } catch (RemoteException e) {
3927            // ignored; service lives in system_server
3928            return false;
3929        } finally {
3930            Binder.restoreCallingIdentity(token);
3931        }
3932    }
3933
3934    /**
3935     * Try refreshing {@link #mTime} when stale.
3936     */
3937    void maybeRefreshTrustedTime() {
3938        if (mTime.getCacheAge() > TIME_CACHE_MAX_AGE) {
3939            mTime.forceRefresh();
3940        }
3941    }
3942
3943    private long currentTimeMillis() {
3944        return mTime.hasCache() ? mTime.currentTimeMillis() : System.currentTimeMillis();
3945    }
3946
3947    private static Intent buildAllowBackgroundDataIntent() {
3948        return new Intent(ACTION_ALLOW_BACKGROUND);
3949    }
3950
3951    private static Intent buildSnoozeWarningIntent(NetworkTemplate template) {
3952        final Intent intent = new Intent(ACTION_SNOOZE_WARNING);
3953        intent.putExtra(EXTRA_NETWORK_TEMPLATE, template);
3954        return intent;
3955    }
3956
3957    private static Intent buildNetworkOverLimitIntent(Resources res, NetworkTemplate template) {
3958        final Intent intent = new Intent();
3959        intent.setComponent(ComponentName.unflattenFromString(
3960                res.getString(R.string.config_networkOverLimitComponent)));
3961        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3962        intent.putExtra(EXTRA_NETWORK_TEMPLATE, template);
3963        return intent;
3964    }
3965
3966    private static Intent buildViewDataUsageIntent(Resources res, NetworkTemplate template) {
3967        final Intent intent = new Intent();
3968        intent.setComponent(ComponentName.unflattenFromString(
3969                res.getString(R.string.config_dataUsageSummaryComponent)));
3970        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3971        intent.putExtra(EXTRA_NETWORK_TEMPLATE, template);
3972        return intent;
3973    }
3974
3975    @VisibleForTesting
3976    public void addIdleHandler(IdleHandler handler) {
3977        mHandler.getLooper().getQueue().addIdleHandler(handler);
3978    }
3979
3980    @VisibleForTesting
3981    public void updateRestrictBackgroundByLowPowerModeUL(final PowerSaveState result) {
3982        mRestrictBackgroundPowerState = result;
3983
3984        boolean restrictBackground = result.batterySaverEnabled;
3985        boolean shouldInvokeRestrictBackground;
3986        // store the temporary mRestrictBackgroundChangedInBsm and update it at last
3987        boolean localRestrictBgChangedInBsm = mRestrictBackgroundChangedInBsm;
3988
3989        if (result.globalBatterySaverEnabled) {
3990            // Try to turn on restrictBackground if (1) it is off and (2) batter saver need to
3991            // turn it on.
3992            shouldInvokeRestrictBackground = !mRestrictBackground && result.batterySaverEnabled;
3993            mRestrictBackgroundBeforeBsm = mRestrictBackground;
3994            localRestrictBgChangedInBsm = false;
3995        } else {
3996            // Try to restore the restrictBackground if it doesn't change in bsm
3997            shouldInvokeRestrictBackground = !mRestrictBackgroundChangedInBsm;
3998            restrictBackground = mRestrictBackgroundBeforeBsm;
3999        }
4000
4001        if (shouldInvokeRestrictBackground) {
4002            setRestrictBackground(restrictBackground);
4003        }
4004
4005        // Change it at last so setRestrictBackground() won't affect this variable
4006        mRestrictBackgroundChangedInBsm = localRestrictBgChangedInBsm;
4007    }
4008
4009    private static void collectKeys(SparseIntArray source, SparseBooleanArray target) {
4010        final int size = source.size();
4011        for (int i = 0; i < size; i++) {
4012            target.put(source.keyAt(i), true);
4013        }
4014    }
4015
4016    @Override
4017    public void factoryReset(String subscriber) {
4018        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
4019
4020        if (mUserManager.hasUserRestriction(UserManager.DISALLOW_NETWORK_RESET)) {
4021            return;
4022        }
4023
4024        // Turn mobile data limit off
4025        NetworkPolicy[] policies = getNetworkPolicies(mContext.getOpPackageName());
4026        NetworkTemplate template = NetworkTemplate.buildTemplateMobileAll(subscriber);
4027        for (NetworkPolicy policy : policies) {
4028            if (policy.template.equals(template)) {
4029                policy.limitBytes = NetworkPolicy.LIMIT_DISABLED;
4030                policy.inferred = false;
4031                policy.clearSnooze();
4032            }
4033        }
4034        setNetworkPolicies(policies);
4035
4036        // Turn restrict background data off
4037        setRestrictBackground(false);
4038
4039        if (!mUserManager.hasUserRestriction(UserManager.DISALLOW_APPS_CONTROL)) {
4040            // Remove app's "restrict background data" flag
4041            for (int uid : getUidsWithPolicy(POLICY_REJECT_METERED_BACKGROUND)) {
4042                setUidPolicy(uid, POLICY_NONE);
4043            }
4044        }
4045    }
4046
4047    private class NetworkPolicyManagerInternalImpl extends NetworkPolicyManagerInternal {
4048
4049        @Override
4050        public void resetUserState(int userId) {
4051            synchronized (mUidRulesFirstLock) {
4052                boolean changed = removeUserStateUL(userId, false);
4053                changed = addDefaultRestrictBackgroundWhitelistUidsUL(userId) || changed;
4054                if (changed) {
4055                    synchronized (mNetworkPoliciesSecondLock) {
4056                        writePolicyAL();
4057                    }
4058                }
4059            }
4060        }
4061
4062        /**
4063         * @return true if the given uid is restricted from doing networking on metered networks.
4064         */
4065        @Override
4066        public boolean isUidRestrictedOnMeteredNetworks(int uid) {
4067            final int uidRules;
4068            final boolean isBackgroundRestricted;
4069            synchronized (mUidRulesFirstLock) {
4070                uidRules = mUidRules.get(uid, RULE_ALLOW_ALL);
4071                isBackgroundRestricted = mRestrictBackground;
4072            }
4073            return isBackgroundRestricted
4074                    && !hasRule(uidRules, RULE_ALLOW_METERED)
4075                    && !hasRule(uidRules, RULE_TEMPORARY_ALLOW_METERED);
4076        }
4077
4078        /**
4079         * @return true if networking is blocked on the given interface for the given uid according
4080         * to current networking policies.
4081         */
4082        @Override
4083        public boolean isUidNetworkingBlocked(int uid, String ifname) {
4084            final int uidRules;
4085            final boolean isBackgroundRestricted;
4086            final boolean isNetworkMetered;
4087            synchronized (mUidRulesFirstLock) {
4088                uidRules = mUidRules.get(uid, RULE_NONE);
4089                isBackgroundRestricted = mRestrictBackground;
4090                synchronized (mNetworkPoliciesSecondLock) {
4091                    isNetworkMetered = mMeteredIfaces.contains(ifname);
4092                }
4093            }
4094            if (hasRule(uidRules, RULE_REJECT_ALL)) {
4095                if (LOGV) logUidStatus(uid, "blocked by power restrictions");
4096                return true;
4097            }
4098            if (!isNetworkMetered) {
4099                if (LOGV) logUidStatus(uid, "allowed on unmetered network");
4100                return false;
4101            }
4102            if (hasRule(uidRules, RULE_REJECT_METERED)) {
4103                if (LOGV) logUidStatus(uid, "blacklisted on metered network");
4104                return true;
4105            }
4106            if (hasRule(uidRules, RULE_ALLOW_METERED)) {
4107                if (LOGV) logUidStatus(uid, "whitelisted on metered network");
4108                return false;
4109            }
4110            if (hasRule(uidRules, RULE_TEMPORARY_ALLOW_METERED)) {
4111                if (LOGV) logUidStatus(uid, "temporary whitelisted on metered network");
4112                return false;
4113            }
4114            if (isBackgroundRestricted) {
4115                if (LOGV) logUidStatus(uid, "blocked when background is restricted");
4116                return true;
4117            }
4118            if (LOGV) logUidStatus(uid, "allowed by default");
4119            return false;
4120        }
4121    }
4122
4123    private static boolean hasRule(int uidRules, int rule) {
4124        return (uidRules & rule) != 0;
4125    }
4126
4127    private static void logUidStatus(int uid, String descr) {
4128        Slog.d(TAG, String.format("uid %d is %s", uid, descr));
4129    }
4130
4131    /**
4132     * This class is used for storing and dumping the last {@link #MAX_PROC_STATE_SEQ_HISTORY}
4133     * (uid, procStateSeq) pairs.
4134     */
4135    @VisibleForTesting
4136    public static final class ProcStateSeqHistory {
4137        private static final int INVALID_UID = -1;
4138
4139        /**
4140         * Denotes maximum number of items this history can hold.
4141         */
4142        private final int mMaxCapacity;
4143        /**
4144         * Used for storing the uid information.
4145         */
4146        private final int[] mUids;
4147        /**
4148         * Used for storing the sequence numbers associated with {@link #mUids}.
4149         */
4150        private final long[] mProcStateSeqs;
4151        /**
4152         * Points to the next available slot for writing (uid, procStateSeq) pair.
4153         */
4154        private int mHistoryNext;
4155
4156        public ProcStateSeqHistory(int maxCapacity) {
4157            mMaxCapacity = maxCapacity;
4158            mUids = new int[mMaxCapacity];
4159            Arrays.fill(mUids, INVALID_UID);
4160            mProcStateSeqs = new long[mMaxCapacity];
4161        }
4162
4163        @GuardedBy("mUidRulesFirstLock")
4164        public void addProcStateSeqUL(int uid, long procStateSeq) {
4165            mUids[mHistoryNext] = uid;
4166            mProcStateSeqs[mHistoryNext] = procStateSeq;
4167            mHistoryNext = increaseNext(mHistoryNext, 1);
4168        }
4169
4170        @GuardedBy("mUidRulesFirstLock")
4171        public void dumpUL(IndentingPrintWriter fout) {
4172            if (mUids[0] == INVALID_UID) {
4173                fout.println("NONE");
4174                return;
4175            }
4176            int index = mHistoryNext;
4177            do {
4178                index = increaseNext(index, -1);
4179                if (mUids[index] == INVALID_UID) {
4180                    break;
4181                }
4182                fout.println(getString(mUids[index], mProcStateSeqs[index]));
4183            } while (index != mHistoryNext);
4184        }
4185
4186        public static String getString(int uid, long procStateSeq) {
4187            return "UID=" + uid + " procStateSeq=" + procStateSeq;
4188        }
4189
4190        private int increaseNext(int next, int increment) {
4191            next += increment;
4192            if (next >= mMaxCapacity) {
4193                next = 0;
4194            } else if (next < 0) {
4195                next = mMaxCapacity - 1;
4196            }
4197            return next;
4198        }
4199    }
4200
4201    private class NotificationId {
4202        private final String mTag;
4203        private final int mId;
4204
4205        NotificationId(NetworkPolicy policy, int type) {
4206            mTag = buildNotificationTag(policy, type);
4207            mId = type;
4208        }
4209
4210        @Override
4211        public boolean equals(Object o) {
4212            if (this == o) return true;
4213            if (!(o instanceof NotificationId)) return false;
4214            NotificationId that = (NotificationId) o;
4215            return Objects.equals(mTag, that.mTag);
4216        }
4217
4218        @Override
4219        public int hashCode() {
4220            return Objects.hash(mTag);
4221        }
4222
4223        /**
4224         * Build unique tag that identifies an active {@link NetworkPolicy}
4225         * notification of a specific type, like {@link #TYPE_LIMIT}.
4226         */
4227        private String buildNotificationTag(NetworkPolicy policy, int type) {
4228            return TAG + ":" + policy.template.hashCode() + ":" + type;
4229        }
4230
4231        public String getTag() {
4232            return mTag;
4233        }
4234
4235        public int getId() {
4236            return mId;
4237        }
4238    }
4239}
4240