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