NetworkPolicyManagerService.java revision 41ff7ec82422a5b6d00892afdb3232bc0e53d851
1d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey/* 2d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey * Copyright (C) 2011 The Android Open Source Project 3d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey * 4d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey * Licensed under the Apache License, Version 2.0 (the "License"); 5d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey * you may not use this file except in compliance with the License. 6d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey * You may obtain a copy of the License at 7d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey * 8d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey * http://www.apache.org/licenses/LICENSE-2.0 9d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey * 10d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey * Unless required by applicable law or agreed to in writing, software 11d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey * distributed under the License is distributed on an "AS IS" BASIS, 12d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey * See the License for the specific language governing permissions and 14d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey * limitations under the License. 15d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey */ 16d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 17d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkeypackage com.android.server.net; 18d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 1921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport static android.Manifest.permission.CONNECTIVITY_INTERNAL; 201b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkeyimport static android.Manifest.permission.DUMP; 21d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkeyimport static android.Manifest.permission.MANAGE_APP_TOKENS; 2221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport static android.Manifest.permission.MANAGE_NETWORK_POLICY; 23497e4437af386930dff3bd55296d128bd4520959Jeff Sharkeyimport static android.Manifest.permission.READ_NETWORK_USAGE_HISTORY; 2422c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkeyimport static android.Manifest.permission.READ_PHONE_STATE; 2502e21d6a5b5117d494777a36783909854854f751Jeff Sharkeyimport static android.content.Intent.ACTION_PACKAGE_ADDED; 26b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkeyimport static android.content.Intent.ACTION_UID_REMOVED; 27b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkeyimport static android.content.Intent.EXTRA_UID; 284e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkeyimport static android.net.ConnectivityManager.ACTION_BACKGROUND_DATA_SETTING_CHANGED; 2921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport static android.net.ConnectivityManager.CONNECTIVITY_ACTION; 301b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkeyimport static android.net.ConnectivityManager.TYPE_MOBILE; 3122c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkeyimport static android.net.NetworkPolicy.LIMIT_DISABLED; 3241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkeyimport static android.net.NetworkPolicy.SNOOZE_NEVER; 33497e4437af386930dff3bd55296d128bd4520959Jeff Sharkeyimport static android.net.NetworkPolicy.WARNING_DISABLED; 3414711eb5b6a45b587222ae71c57a381beb7b1a7eJeff Sharkeyimport static android.net.NetworkPolicyManager.EXTRA_NETWORK_TEMPLATE; 35d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkeyimport static android.net.NetworkPolicyManager.POLICY_NONE; 36fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkeyimport static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND; 37c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkeyimport static android.net.NetworkPolicyManager.RULE_ALLOW_ALL; 38fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkeyimport static android.net.NetworkPolicyManager.RULE_REJECT_METERED; 39cd2ca4038a027315832c38c68be5076000bc4b53Jeff Sharkeyimport static android.net.NetworkPolicyManager.computeLastCycleBoundary; 401b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkeyimport static android.net.NetworkPolicyManager.dumpPolicy; 411b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkeyimport static android.net.NetworkPolicyManager.dumpRules; 42497e4437af386930dff3bd55296d128bd4520959Jeff Sharkeyimport static android.net.NetworkPolicyManager.isUidValidForPolicy; 431b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkeyimport static android.net.NetworkTemplate.MATCH_MOBILE_3G_LOWER; 441b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkeyimport static android.net.NetworkTemplate.MATCH_MOBILE_4G; 454e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkeyimport static android.net.NetworkTemplate.buildTemplateMobileAll; 4621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport static android.text.format.DateUtils.DAY_IN_MILLIS; 4721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport static com.android.internal.util.Preconditions.checkNotNull; 48497e4437af386930dff3bd55296d128bd4520959Jeff Sharkeyimport static com.android.server.net.NetworkStatsService.ACTION_NETWORK_STATS_UPDATED; 4921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 5021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport static org.xmlpull.v1.XmlPullParser.START_TAG; 51d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 52a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkeyimport android.app.IActivityManager; 53497e4437af386930dff3bd55296d128bd4520959Jeff Sharkeyimport android.app.INotificationManager; 54a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkeyimport android.app.IProcessObserver; 55497e4437af386930dff3bd55296d128bd4520959Jeff Sharkeyimport android.app.Notification; 56497e4437af386930dff3bd55296d128bd4520959Jeff Sharkeyimport android.app.PendingIntent; 57a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkeyimport android.content.BroadcastReceiver; 5841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkeyimport android.content.ComponentName; 59d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkeyimport android.content.Context; 60a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkeyimport android.content.Intent; 61a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkeyimport android.content.IntentFilter; 62b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkeyimport android.content.pm.ApplicationInfo; 63b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkeyimport android.content.pm.PackageManager; 64497e4437af386930dff3bd55296d128bd4520959Jeff Sharkeyimport android.content.res.Resources; 65c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkeyimport android.net.ConnectivityManager; 6621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport android.net.IConnectivityManager; 6741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkeyimport android.net.INetworkManagementEventObserver; 68c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkeyimport android.net.INetworkPolicyListener; 69d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkeyimport android.net.INetworkPolicyManager; 7075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.net.INetworkStatsService; 711b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkeyimport android.net.NetworkIdentity; 7221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport android.net.NetworkPolicy; 7321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport android.net.NetworkState; 7421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport android.net.NetworkStats; 751b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkeyimport android.net.NetworkTemplate; 7621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport android.os.Environment; 7721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport android.os.Handler; 7821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport android.os.HandlerThread; 7950fd36d7c38c40b087c8f3e3172478abe0c051d9Ashish Sharmaimport android.os.INetworkManagementService; 80a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkeyimport android.os.IPowerManager; 814414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkeyimport android.os.Message; 82c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkeyimport android.os.RemoteCallbackList; 83a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkeyimport android.os.RemoteException; 8422c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkeyimport android.telephony.TelephonyManager; 85497e4437af386930dff3bd55296d128bd4520959Jeff Sharkeyimport android.text.format.Formatter; 8622c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkeyimport android.text.format.Time; 8721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport android.util.NtpTrustedTime; 88a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkeyimport android.util.Slog; 89d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkeyimport android.util.SparseArray; 90d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkeyimport android.util.SparseBooleanArray; 91d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkeyimport android.util.SparseIntArray; 9221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport android.util.TrustedTime; 9321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport android.util.Xml; 94d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 95497e4437af386930dff3bd55296d128bd4520959Jeff Sharkeyimport com.android.internal.R; 9621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport com.android.internal.os.AtomicFile; 9721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport com.android.internal.util.FastXmlSerializer; 9821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport com.google.android.collect.Lists; 9921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport com.google.android.collect.Maps; 100fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkeyimport com.google.android.collect.Sets; 10121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 10221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport org.xmlpull.v1.XmlPullParser; 10321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport org.xmlpull.v1.XmlPullParserException; 10421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport org.xmlpull.v1.XmlSerializer; 10521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 10621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport java.io.File; 1071b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkeyimport java.io.FileDescriptor; 10821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport java.io.FileInputStream; 10921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport java.io.FileNotFoundException; 11021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport java.io.FileOutputStream; 11121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport java.io.IOException; 1121b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkeyimport java.io.PrintWriter; 11321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport java.net.ProtocolException; 11421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport java.util.ArrayList; 11521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport java.util.Arrays; 11621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport java.util.HashMap; 117fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkeyimport java.util.HashSet; 118b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkeyimport java.util.List; 11921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 12021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport libcore.io.IoUtils; 1211b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey 122d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey/** 123d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey * Service that maintains low-level network policy rules and collects usage 124d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey * statistics to drive those rules. 125c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey * <p> 126c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey * Derives active rules by combining a given policy with other system status, 127c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey * and delivers to listeners, such as {@link ConnectivityManager}, for 128c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey * enforcement. 129d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey */ 130d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkeypublic class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { 131d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey private static final String TAG = "NetworkPolicy"; 132d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey private static final boolean LOGD = true; 13322c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey private static final boolean LOGV = false; 134d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 13541ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey private static final int VERSION_INIT = 1; 13641ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey private static final int VERSION_ADDED_SNOOZE = 2; 13721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 13822c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey private static final long KB_IN_BYTES = 1024; 13922c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey private static final long MB_IN_BYTES = KB_IN_BYTES * 1024; 14022c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey private static final long GB_IN_BYTES = MB_IN_BYTES * 1024; 14122c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey 14241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey // @VisibleForTesting 14341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey public static final int TYPE_WARNING = 0x1; 14441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey public static final int TYPE_LIMIT = 0x2; 14541ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey public static final int TYPE_LIMIT_SNOOZED = 0x3; 146497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey 14721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private static final String TAG_POLICY_LIST = "policy-list"; 14821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private static final String TAG_NETWORK_POLICY = "network-policy"; 14921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private static final String TAG_UID_POLICY = "uid-policy"; 15021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 15121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private static final String ATTR_VERSION = "version"; 15221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private static final String ATTR_NETWORK_TEMPLATE = "networkTemplate"; 15321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private static final String ATTR_SUBSCRIBER_ID = "subscriberId"; 15421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private static final String ATTR_CYCLE_DAY = "cycleDay"; 15521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private static final String ATTR_WARNING_BYTES = "warningBytes"; 15621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private static final String ATTR_LIMIT_BYTES = "limitBytes"; 15741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey private static final String ATTR_LAST_SNOOZE = "lastSnooze"; 15821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private static final String ATTR_UID = "uid"; 15921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private static final String ATTR_POLICY = "policy"; 16021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 16121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private static final long TIME_CACHE_MAX_AGE = DAY_IN_MILLIS; 16221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 1634414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey private static final int MSG_RULES_CHANGED = 0x1; 1644414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey private static final int MSG_METERED_IFACES_CHANGED = 0x2; 1654414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey 16675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey private final Context mContext; 16775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey private final IActivityManager mActivityManager; 16875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey private final IPowerManager mPowerManager; 16975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey private final INetworkStatsService mNetworkStats; 17041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey private final INetworkManagementService mNetworkManager; 17121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private final TrustedTime mTime; 17221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 17321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private IConnectivityManager mConnManager; 174497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey private INotificationManager mNotifManager; 175a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey 17675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey private final Object mRulesLock = new Object(); 177a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey 178c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey private boolean mScreenOn; 179b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey private boolean mBackgroundData; 180d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 18141ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey /** Defined network policies. */ 18241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey private HashMap<NetworkTemplate, NetworkPolicy> mNetworkPolicy = Maps.newHashMap(); 18341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey /** Currently active network rules for ifaces. */ 18402e21d6a5b5117d494777a36783909854854f751Jeff Sharkey private HashMap<NetworkPolicy, String[]> mNetworkRules = Maps.newHashMap(); 18522c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey 18641ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey /** Defined UID policies. */ 187a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey private SparseIntArray mUidPolicy = new SparseIntArray(); 18841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey /** Currently derived rules for each UID. */ 189c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey private SparseIntArray mUidRules = new SparseIntArray(); 190d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 191fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey /** Set of ifaces that are metered. */ 192fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey private HashSet<String> mMeteredIfaces = Sets.newHashSet(); 19341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey /** Set of over-limit templates that have been notified. */ 19441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey private HashSet<NetworkTemplate> mOverLimitNotified = Sets.newHashSet(); 195fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey 196d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey /** Foreground at both UID and PID granularity. */ 197a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey private SparseBooleanArray mUidForeground = new SparseBooleanArray(); 198a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey private SparseArray<SparseBooleanArray> mUidPidForeground = new SparseArray< 199a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey SparseBooleanArray>(); 200d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 201c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey private final RemoteCallbackList<INetworkPolicyListener> mListeners = new RemoteCallbackList< 202c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey INetworkPolicyListener>(); 203c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey 20421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private final HandlerThread mHandlerThread; 20521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private final Handler mHandler; 20621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 20721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private final AtomicFile mPolicyFile; 208d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 209c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey // TODO: keep whitelist of system-critical services that should never have 210c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey // rules enforced, such as system, phone, and radio UIDs. 211c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey 21241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey // TODO: migrate notifications to SystemUI 21341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey 21475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey public NetworkPolicyManagerService(Context context, IActivityManager activityManager, 21550fd36d7c38c40b087c8f3e3172478abe0c051d9Ashish Sharma IPowerManager powerManager, INetworkStatsService networkStats, 21650fd36d7c38c40b087c8f3e3172478abe0c051d9Ashish Sharma INetworkManagementService networkManagement) { 217b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey this(context, activityManager, powerManager, networkStats, networkManagement, 218104344e507610be42fb70c7deda3c422c543bfcbJeff Sharkey NtpTrustedTime.getInstance(context), getSystemDir()); 21921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 22021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 22121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private static File getSystemDir() { 22221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey return new File(Environment.getDataDirectory(), "system"); 22321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 22421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 22521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey public NetworkPolicyManagerService(Context context, IActivityManager activityManager, 22650fd36d7c38c40b087c8f3e3172478abe0c051d9Ashish Sharma IPowerManager powerManager, INetworkStatsService networkStats, 22750fd36d7c38c40b087c8f3e3172478abe0c051d9Ashish Sharma INetworkManagementService networkManagement, 22850fd36d7c38c40b087c8f3e3172478abe0c051d9Ashish Sharma TrustedTime time, File systemDir) { 229a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey mContext = checkNotNull(context, "missing context"); 230a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey mActivityManager = checkNotNull(activityManager, "missing activityManager"); 231a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey mPowerManager = checkNotNull(powerManager, "missing powerManager"); 23275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey mNetworkStats = checkNotNull(networkStats, "missing networkStats"); 23341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey mNetworkManager = checkNotNull(networkManagement, "missing networkManagement"); 23421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey mTime = checkNotNull(time, "missing TrustedTime"); 23521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 23621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey mHandlerThread = new HandlerThread(TAG); 23721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey mHandlerThread.start(); 2384414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey mHandler = new Handler(mHandlerThread.getLooper(), mHandlerCallback); 23921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 24021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey mPolicyFile = new AtomicFile(new File(systemDir, "netpolicy.xml")); 24121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 24221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 24321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey public void bindConnectivityManager(IConnectivityManager connManager) { 24421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey mConnManager = checkNotNull(connManager, "missing IConnectivityManager"); 245a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 246d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 247497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey public void bindNotificationManager(INotificationManager notifManager) { 248497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey mNotifManager = checkNotNull(notifManager, "missing INotificationManager"); 249497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey } 250497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey 251a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey public void systemReady() { 25221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey synchronized (mRulesLock) { 25321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey // read policy from disk 25421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey readPolicyLocked(); 25521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 256d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 257a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey updateScreenOn(); 258b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey updateBackgroundData(true); 259d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 260a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey try { 261a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey mActivityManager.registerProcessObserver(mProcessObserver); 262a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } catch (RemoteException e) { 263a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey // ouch, no foregroundActivities updates means some processes may 264a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey // never get network access. 265a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey Slog.e(TAG, "unable to register IProcessObserver", e); 266a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 267d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 26841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey try { 26941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey mNetworkManager.registerObserver(mAlertObserver); 27041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey } catch (RemoteException e) { 27141ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey // ouch, no alert updates means we fall back to 27241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey // ACTION_NETWORK_STATS_UPDATED broadcasts. 27341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey Slog.e(TAG, "unable to register INetworkManagementEventObserver", e); 27441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey } 27541ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey 276a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey // TODO: traverse existing processes to know foreground state, or have 277a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey // activitymanager dispatch current state when new observer attached. 278d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 279a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey final IntentFilter screenFilter = new IntentFilter(); 280a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey screenFilter.addAction(Intent.ACTION_SCREEN_ON); 281a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey screenFilter.addAction(Intent.ACTION_SCREEN_OFF); 28241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey mContext.registerReceiver(mScreenReceiver, screenFilter, null, mHandler); 283d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 28421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey // watch for network interfaces to be claimed 285b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey final IntentFilter connFilter = new IntentFilter(CONNECTIVITY_ACTION); 286b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey mContext.registerReceiver(mConnReceiver, connFilter, CONNECTIVITY_INTERNAL, mHandler); 287b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey 28802e21d6a5b5117d494777a36783909854854f751Jeff Sharkey // listen for package/uid changes to update policy 28902e21d6a5b5117d494777a36783909854854f751Jeff Sharkey final IntentFilter packageFilter = new IntentFilter(); 29002e21d6a5b5117d494777a36783909854854f751Jeff Sharkey packageFilter.addAction(ACTION_PACKAGE_ADDED); 29102e21d6a5b5117d494777a36783909854854f751Jeff Sharkey packageFilter.addAction(ACTION_UID_REMOVED); 29202e21d6a5b5117d494777a36783909854854f751Jeff Sharkey mContext.registerReceiver(mPackageReceiver, packageFilter, null, mHandler); 29321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 294b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey // listen for stats update events 295497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey final IntentFilter statsFilter = new IntentFilter(ACTION_NETWORK_STATS_UPDATED); 296497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey mContext.registerReceiver( 297497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey mStatsReceiver, statsFilter, READ_NETWORK_USAGE_HISTORY, mHandler); 298497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey 299b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey // listen for changes to background data flag 300b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey final IntentFilter bgFilter = new IntentFilter(ACTION_BACKGROUND_DATA_SETTING_CHANGED); 301b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey mContext.registerReceiver(mBgReceiver, bgFilter, CONNECTIVITY_INTERNAL, mHandler); 302b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey 303a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 304d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 305a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey private IProcessObserver mProcessObserver = new IProcessObserver.Stub() { 306a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey @Override 307a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey public void onForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities) { 308a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey // only someone like AMS should only be calling us 30975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey mContext.enforceCallingOrSelfPermission(MANAGE_APP_TOKENS, TAG); 310a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey 311a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey synchronized (mRulesLock) { 312a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey // because a uid can have multiple pids running inside, we need to 313a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey // remember all pid states and summarize foreground at uid level. 314a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey 315a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey // record foreground for this specific pid 316a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey SparseBooleanArray pidForeground = mUidPidForeground.get(uid); 317a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey if (pidForeground == null) { 318a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey pidForeground = new SparseBooleanArray(2); 319a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey mUidPidForeground.put(uid, pidForeground); 320a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 321a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey pidForeground.put(pid, foregroundActivities); 32221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey computeUidForegroundLocked(uid); 323a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 324d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey } 325d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 326a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey @Override 327a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey public void onProcessDied(int pid, int uid) { 328a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey // only someone like AMS should only be calling us 32975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey mContext.enforceCallingOrSelfPermission(MANAGE_APP_TOKENS, TAG); 330a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey 331a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey synchronized (mRulesLock) { 332a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey // clear records and recompute, when they exist 333a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey final SparseBooleanArray pidForeground = mUidPidForeground.get(uid); 334a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey if (pidForeground != null) { 335a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey pidForeground.delete(pid); 33621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey computeUidForegroundLocked(uid); 337a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 338a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 339a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 340a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey }; 341a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey 342a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey private BroadcastReceiver mScreenReceiver = new BroadcastReceiver() { 343a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey @Override 344a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey public void onReceive(Context context, Intent intent) { 345a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey synchronized (mRulesLock) { 346a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey // screen-related broadcasts are protected by system, no need 347a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey // for permissions check. 348a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey updateScreenOn(); 349a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 350a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 351a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey }; 352d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 35302e21d6a5b5117d494777a36783909854854f751Jeff Sharkey private BroadcastReceiver mPackageReceiver = new BroadcastReceiver() { 354b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey @Override 355b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey public void onReceive(Context context, Intent intent) { 35602e21d6a5b5117d494777a36783909854854f751Jeff Sharkey // on background handler thread, and PACKAGE_ADDED and UID_REMOVED 35702e21d6a5b5117d494777a36783909854854f751Jeff Sharkey // are protected broadcasts. 35802e21d6a5b5117d494777a36783909854854f751Jeff Sharkey 35902e21d6a5b5117d494777a36783909854854f751Jeff Sharkey final String action = intent.getAction(); 360b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey final int uid = intent.getIntExtra(EXTRA_UID, 0); 361b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey synchronized (mRulesLock) { 36202e21d6a5b5117d494777a36783909854854f751Jeff Sharkey if (ACTION_PACKAGE_ADDED.equals(action)) { 36302e21d6a5b5117d494777a36783909854854f751Jeff Sharkey // update rules for UID, since it might be subject to 36402e21d6a5b5117d494777a36783909854854f751Jeff Sharkey // global background data policy. 36502e21d6a5b5117d494777a36783909854854f751Jeff Sharkey if (LOGV) Slog.v(TAG, "ACTION_PACKAGE_ADDED for uid=" + uid); 36602e21d6a5b5117d494777a36783909854854f751Jeff Sharkey updateRulesForUidLocked(uid); 36702e21d6a5b5117d494777a36783909854854f751Jeff Sharkey 36802e21d6a5b5117d494777a36783909854854f751Jeff Sharkey } else if (ACTION_UID_REMOVED.equals(action)) { 36902e21d6a5b5117d494777a36783909854854f751Jeff Sharkey // remove any policy and update rules to clean up. 37002e21d6a5b5117d494777a36783909854854f751Jeff Sharkey if (LOGV) Slog.v(TAG, "ACTION_UID_REMOVED for uid=" + uid); 37102e21d6a5b5117d494777a36783909854854f751Jeff Sharkey mUidPolicy.delete(uid); 37202e21d6a5b5117d494777a36783909854854f751Jeff Sharkey updateRulesForUidLocked(uid); 37302e21d6a5b5117d494777a36783909854854f751Jeff Sharkey writePolicyLocked(); 37402e21d6a5b5117d494777a36783909854854f751Jeff Sharkey } 375b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey } 376b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey } 377b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey }; 378b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey 37921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey /** 380497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey * Receiver that watches for {@link INetworkStatsService} updates, which we 381497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey * use to check against {@link NetworkPolicy#warningBytes}. 382497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey */ 383497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey private BroadcastReceiver mStatsReceiver = new BroadcastReceiver() { 384497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey @Override 385497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey public void onReceive(Context context, Intent intent) { 386497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey // on background handler thread, and verified 387497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey // READ_NETWORK_USAGE_HISTORY permission above. 388497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey 389497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey synchronized (mRulesLock) { 390497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey updateNotificationsLocked(); 391497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey } 392497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey } 393497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey }; 394497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey 395497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey /** 396b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey * Receiver that watches for 397b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey * {@link #ACTION_BACKGROUND_DATA_SETTING_CHANGED}. 398b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey */ 399b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey private BroadcastReceiver mBgReceiver = new BroadcastReceiver() { 400b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey @Override 401b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey public void onReceive(Context context, Intent intent) { 402b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey // on background handler thread, and verified CONNECTIVITY_INTERNAL 403b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey // permission above. 404b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey 405b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey synchronized (mRulesLock) { 406b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey updateBackgroundData(false); 407b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey } 408b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey } 409b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey }; 410b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey 411b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey /** 41241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey * Observer that watches for {@link INetworkManagementService} alerts. 41341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey */ 41441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey private INetworkManagementEventObserver mAlertObserver = new NetworkAlertObserver() { 41541ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey @Override 41641ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey public void limitReached(String limitName, String iface) { 41741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey // only someone like NMS should be calling us 41841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 41941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey 42041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey synchronized (mRulesLock) { 42141ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey if (mMeteredIfaces.contains(iface)) { 42241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey try { 42341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey // force stats update to make sure we have numbers that 42441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey // caused alert to trigger. 42541ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey mNetworkStats.forceUpdate(); 42641ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey } catch (RemoteException e) { 42741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey Slog.w(TAG, "problem updating network stats"); 42841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey } 42941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey 43041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey updateNotificationsLocked(); 43141ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey } 43241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey } 43341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey } 43441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey }; 43541ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey 43641ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey /** 437497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey * Check {@link NetworkPolicy} against current {@link INetworkStatsService} 438497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey * to show visible notifications as needed. 439497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey */ 440497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey private void updateNotificationsLocked() { 441497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey if (LOGV) Slog.v(TAG, "updateNotificationsLocked()"); 442497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey 443497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey // try refreshing time source when stale 444497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey if (mTime.getCacheAge() > TIME_CACHE_MAX_AGE) { 445497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey mTime.forceRefresh(); 446497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey } 447497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey 448497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey final long currentTime = mTime.hasCache() ? mTime.currentTimeMillis() 449497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey : System.currentTimeMillis(); 450497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey 451497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey // TODO: when switching to kernel notifications, compute next future 452497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey // cycle boundary to recompute notifications. 453497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey 45402e21d6a5b5117d494777a36783909854854f751Jeff Sharkey // examine stats for each active policy 45502e21d6a5b5117d494777a36783909854854f751Jeff Sharkey for (NetworkPolicy policy : mNetworkRules.keySet()) { 456497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey final long start = computeLastCycleBoundary(currentTime, policy); 457497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey final long end = currentTime; 458497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey 45941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey final long totalBytes; 460497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey try { 461497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey final NetworkStats stats = mNetworkStats.getSummaryForNetwork( 4621b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey policy.template, start, end); 463d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey final NetworkStats.Entry entry = stats.getValues(0, null); 46441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey totalBytes = entry.rxBytes + entry.txBytes; 465497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey } catch (RemoteException e) { 4661b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey Slog.w(TAG, "problem reading summary for template " + policy.template); 467497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey continue; 468497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey } 469497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey 47041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey if (policy.limitBytes != LIMIT_DISABLED && totalBytes >= policy.limitBytes) { 471497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey cancelNotification(policy, TYPE_WARNING); 47241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey 47341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey if (policy.lastSnooze >= start) { 47441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey cancelNotification(policy, TYPE_LIMIT); 47541ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey enqueueNotification(policy, TYPE_LIMIT_SNOOZED, totalBytes); 47641ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey } else { 47741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey cancelNotification(policy, TYPE_LIMIT_SNOOZED); 47841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey enqueueNotification(policy, TYPE_LIMIT, totalBytes); 47941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey notifyOverLimitLocked(policy.template); 48041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey } 48141ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey 482497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey } else { 483497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey cancelNotification(policy, TYPE_LIMIT); 48441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey cancelNotification(policy, TYPE_LIMIT_SNOOZED); 48541ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey notifyUnderLimitLocked(policy.template); 486497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey 48741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey if (policy.warningBytes != WARNING_DISABLED && totalBytes >= policy.warningBytes) { 48841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey enqueueNotification(policy, TYPE_WARNING, totalBytes); 489497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey } else { 490497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey cancelNotification(policy, TYPE_WARNING); 491497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey } 492497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey } 49302e21d6a5b5117d494777a36783909854854f751Jeff Sharkey } 49402e21d6a5b5117d494777a36783909854854f751Jeff Sharkey 49502e21d6a5b5117d494777a36783909854854f751Jeff Sharkey // clear notifications for non-active policies 49641ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey for (NetworkPolicy policy : mNetworkPolicy.values()) { 49702e21d6a5b5117d494777a36783909854854f751Jeff Sharkey if (!mNetworkRules.containsKey(policy)) { 49802e21d6a5b5117d494777a36783909854854f751Jeff Sharkey cancelNotification(policy, TYPE_WARNING); 49902e21d6a5b5117d494777a36783909854854f751Jeff Sharkey cancelNotification(policy, TYPE_LIMIT); 50041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey cancelNotification(policy, TYPE_LIMIT_SNOOZED); 50141ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey notifyUnderLimitLocked(policy.template); 50202e21d6a5b5117d494777a36783909854854f751Jeff Sharkey } 503497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey } 504497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey } 505497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey 506497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey /** 50741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey * Notify that given {@link NetworkTemplate} is over 50841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey * {@link NetworkPolicy#limitBytes}, potentially showing dialog to user. 50941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey */ 51041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey private void notifyOverLimitLocked(NetworkTemplate template) { 51141ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey if (!mOverLimitNotified.contains(template)) { 51241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey mContext.startActivity(buildNetworkOverLimitIntent(template)); 51341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey mOverLimitNotified.add(template); 51441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey } 51541ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey } 51641ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey 51741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey private void notifyUnderLimitLocked(NetworkTemplate template) { 51841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey mOverLimitNotified.remove(template); 51941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey } 52041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey 52141ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey /** 522497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey * Build unique tag that identifies an active {@link NetworkPolicy} 523497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey * notification of a specific type, like {@link #TYPE_LIMIT}. 524497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey */ 525497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey private String buildNotificationTag(NetworkPolicy policy, int type) { 5261b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey return TAG + ":" + policy.template.hashCode() + ":" + type; 527497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey } 528497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey 529497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey /** 530497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey * Show notification for combined {@link NetworkPolicy} and specific type, 531497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey * like {@link #TYPE_LIMIT}. Okay to call multiple times. 532497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey */ 53341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey private void enqueueNotification(NetworkPolicy policy, int type, long totalBytes) { 534497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey final String tag = buildNotificationTag(policy, type); 535497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey final Notification.Builder builder = new Notification.Builder(mContext); 536497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey builder.setOnlyAlertOnce(true); 537497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey builder.setOngoing(true); 538497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey 539497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey final Resources res = mContext.getResources(); 540497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey switch (type) { 541497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey case TYPE_WARNING: { 54241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey final CharSequence title = res.getText(R.string.data_usage_warning_title); 54341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey final CharSequence body = res.getString(R.string.data_usage_warning_body, 544497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey Formatter.formatFileSize(mContext, policy.warningBytes)); 545497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey 546497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey builder.setSmallIcon(R.drawable.ic_menu_info_details); 547497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey builder.setTicker(title); 548497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey builder.setContentTitle(title); 549497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey builder.setContentText(body); 55014711eb5b6a45b587222ae71c57a381beb7b1a7eJeff Sharkey 55141ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey final Intent intent = buildViewDataUsageIntent(policy.template); 55214711eb5b6a45b587222ae71c57a381beb7b1a7eJeff Sharkey builder.setContentIntent(PendingIntent.getActivity( 55314711eb5b6a45b587222ae71c57a381beb7b1a7eJeff Sharkey mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)); 554497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey break; 555497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey } 556497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey case TYPE_LIMIT: { 55741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey final CharSequence body = res.getText(R.string.data_usage_limit_body); 55841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey 55941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey final CharSequence title; 5601b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey switch (policy.template.getMatchRule()) { 5611b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey case MATCH_MOBILE_3G_LOWER: 56241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey title = res.getText(R.string.data_usage_3g_limit_title); 563497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey break; 5641b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey case MATCH_MOBILE_4G: 56541ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey title = res.getText(R.string.data_usage_4g_limit_title); 566497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey break; 567497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey default: 56841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey title = res.getText(R.string.data_usage_mobile_limit_title); 569497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey break; 570497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey } 571497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey 572497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey builder.setSmallIcon(com.android.internal.R.drawable.ic_menu_block); 573497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey builder.setTicker(title); 574497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey builder.setContentTitle(title); 575497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey builder.setContentText(body); 57614711eb5b6a45b587222ae71c57a381beb7b1a7eJeff Sharkey 57741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey final Intent intent = buildNetworkOverLimitIntent(policy.template); 57841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey builder.setContentIntent(PendingIntent.getActivity( 57941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)); 58041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey break; 58141ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey } 58241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey case TYPE_LIMIT_SNOOZED: { 58341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey final long overBytes = totalBytes - policy.limitBytes; 58441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey final CharSequence body = res.getString(R.string.data_usage_limit_snoozed_body, 58541ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey Formatter.formatFileSize(mContext, overBytes)); 58641ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey 58741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey final CharSequence title; 58841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey switch (policy.template.getMatchRule()) { 58941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey case MATCH_MOBILE_3G_LOWER: 59041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey title = res.getText(R.string.data_usage_3g_limit_snoozed_title); 59141ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey break; 59241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey case MATCH_MOBILE_4G: 59341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey title = res.getText(R.string.data_usage_4g_limit_snoozed_title); 59441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey break; 59541ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey default: 59641ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey title = res.getText(R.string.data_usage_mobile_limit_snoozed_title); 59741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey break; 59841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey } 59941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey 60041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey builder.setSmallIcon(R.drawable.ic_menu_info_details); 60141ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey builder.setTicker(title); 60241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey builder.setContentTitle(title); 60341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey builder.setContentText(body); 60441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey 60541ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey final Intent intent = buildViewDataUsageIntent(policy.template); 60614711eb5b6a45b587222ae71c57a381beb7b1a7eJeff Sharkey builder.setContentIntent(PendingIntent.getActivity( 60714711eb5b6a45b587222ae71c57a381beb7b1a7eJeff Sharkey mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)); 608497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey break; 609497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey } 610497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey } 611497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey 612497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey // TODO: move to NotificationManager once we can mock it 613497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey try { 614497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey final String packageName = mContext.getPackageName(); 615497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey final int[] idReceived = new int[1]; 616497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey mNotifManager.enqueueNotificationWithTag( 617497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey packageName, tag, 0x0, builder.getNotification(), idReceived); 618497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey } catch (RemoteException e) { 619497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey Slog.w(TAG, "problem during enqueueNotification: " + e); 620497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey } 621497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey } 622497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey 623497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey /** 624497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey * Cancel any notification for combined {@link NetworkPolicy} and specific 625497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey * type, like {@link #TYPE_LIMIT}. 626497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey */ 627497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey private void cancelNotification(NetworkPolicy policy, int type) { 628497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey final String tag = buildNotificationTag(policy, type); 629497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey 630497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey // TODO: move to NotificationManager once we can mock it 631497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey try { 632497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey final String packageName = mContext.getPackageName(); 633497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey mNotifManager.cancelNotificationWithTag(packageName, tag, 0x0); 634497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey } catch (RemoteException e) { 635497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey Slog.w(TAG, "problem during enqueueNotification: " + e); 636497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey } 637497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey } 638497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey 639497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey /** 64021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey * Receiver that watches for {@link IConnectivityManager} to claim network 64122c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey * interfaces. Used to apply {@link NetworkPolicy} to matching networks. 64221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey */ 643b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey private BroadcastReceiver mConnReceiver = new BroadcastReceiver() { 64421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey @Override 64521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey public void onReceive(Context context, Intent intent) { 64621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey // on background handler thread, and verified CONNECTIVITY_INTERNAL 64721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey // permission above. 64821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey synchronized (mRulesLock) { 64922c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey ensureActiveMobilePolicyLocked(); 65002e21d6a5b5117d494777a36783909854854f751Jeff Sharkey updateNetworkRulesLocked(); 65102e21d6a5b5117d494777a36783909854854f751Jeff Sharkey updateNotificationsLocked(); 65221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 65321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 65421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey }; 65521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 65621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey /** 65721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey * Examine all connected {@link NetworkState}, looking for 65821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey * {@link NetworkPolicy} that need to be enforced. When matches found, set 65921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey * remaining quota based on usage cycle and historical stats. 66021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey */ 66102e21d6a5b5117d494777a36783909854854f751Jeff Sharkey private void updateNetworkRulesLocked() { 66222c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey if (LOGV) Slog.v(TAG, "updateIfacesLocked()"); 66321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 66421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final NetworkState[] states; 66521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey try { 66621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey states = mConnManager.getAllNetworkState(); 66721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } catch (RemoteException e) { 66821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey Slog.w(TAG, "problem reading network state"); 66921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey return; 67021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 67121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 67221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey // first, derive identity for all connected networks, which can be used 67321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey // to match against templates. 67421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final HashMap<NetworkIdentity, String> networks = Maps.newHashMap(); 67521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey for (NetworkState state : states) { 67621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey // stash identity and iface away for later use 67721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey if (state.networkInfo.isConnected()) { 67821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final String iface = state.linkProperties.getInterfaceName(); 67921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state); 68021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey networks.put(ident, iface); 68121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 68221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 68321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 68421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey // build list of rules and ifaces to enforce them against 68502e21d6a5b5117d494777a36783909854854f751Jeff Sharkey mNetworkRules.clear(); 68621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final ArrayList<String> ifaceList = Lists.newArrayList(); 68741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey for (NetworkPolicy policy : mNetworkPolicy.values()) { 68821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 68921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey // collect all active ifaces that match this template 69021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey ifaceList.clear(); 69121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey for (NetworkIdentity ident : networks.keySet()) { 6921b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey if (policy.template.matches(ident)) { 69321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final String iface = networks.get(ident); 69421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey ifaceList.add(iface); 69521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 69621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 69721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 69821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey if (ifaceList.size() > 0) { 69921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final String[] ifaces = ifaceList.toArray(new String[ifaceList.size()]); 70002e21d6a5b5117d494777a36783909854854f751Jeff Sharkey mNetworkRules.put(policy, ifaces); 70121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 70221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 70321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 70421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey // try refreshing time source when stale 70521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey if (mTime.getCacheAge() > TIME_CACHE_MAX_AGE) { 70621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey mTime.forceRefresh(); 70721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 70821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 70921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final long currentTime = mTime.hasCache() ? mTime.currentTimeMillis() 71021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey : System.currentTimeMillis(); 71121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 712b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey final HashSet<String> newMeteredIfaces = Sets.newHashSet(); 713fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey 71421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey // apply each policy that we found ifaces for; compute remaining data 71521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey // based on current cycle and historical stats, and push to kernel. 71602e21d6a5b5117d494777a36783909854854f751Jeff Sharkey for (NetworkPolicy policy : mNetworkRules.keySet()) { 71702e21d6a5b5117d494777a36783909854854f751Jeff Sharkey final String[] ifaces = mNetworkRules.get(policy); 71821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 71921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final long start = computeLastCycleBoundary(currentTime, policy); 72021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final long end = currentTime; 72121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 72221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final NetworkStats stats; 72322c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey final long total; 72421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey try { 7251b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey stats = mNetworkStats.getSummaryForNetwork(policy.template, start, end); 726d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey final NetworkStats.Entry entry = stats.getValues(0, null); 727d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey total = entry.rxBytes + entry.txBytes; 72821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } catch (RemoteException e) { 7291b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey Slog.w(TAG, "problem reading summary for template " + policy.template); 73021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey continue; 73121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 73221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 73321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey if (LOGD) { 73421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey Slog.d(TAG, "applying policy " + policy.toString() + " to ifaces " 73522c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey + Arrays.toString(ifaces)); 73622c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey } 73722c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey 73841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey final boolean hasLimit = policy.limitBytes != LIMIT_DISABLED; 73941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey final boolean hasWarning = policy.warningBytes != WARNING_DISABLED; 74022c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey 74141ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey if (hasLimit || hasWarning) { 74241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey final long quotaBytes; 74341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey if (hasLimit) { 74441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey // remaining "quota" is based on usage in current cycle 74541ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey quotaBytes = Math.max(0, policy.limitBytes - total); 74641ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey } else { 74741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey // to track warning alert later, use a high quota 74841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey quotaBytes = Long.MAX_VALUE; 74941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey } 75050fd36d7c38c40b087c8f3e3172478abe0c051d9Ashish Sharma 751b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey if (ifaces.length > 1) { 752b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey // TODO: switch to shared quota once NMS supports 753b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey Slog.w(TAG, "shared quota unsupported; generating rule for each iface"); 754b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey } 755fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey 756fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey for (String iface : ifaces) { 757b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey removeInterfaceQuota(iface); 75841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey if (quotaBytes > 0) { 75941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey setInterfaceQuota(iface, quotaBytes); 76041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey newMeteredIfaces.add(iface); 76141ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey } 76241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey } 76341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey } 76441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey 76541ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey if (hasWarning) { 76641ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey final long alertBytes = Math.max(0, policy.warningBytes - total); 76741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey for (String iface : ifaces) { 76841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey removeInterfaceAlert(iface); 76941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey if (alertBytes > 0) { 77041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey setInterfaceAlert(iface, alertBytes); 77141ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey } 772fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey } 77322c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey } 77422c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey } 775fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey 776b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey // remove quota on any trailing interfaces 777b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey for (String iface : mMeteredIfaces) { 778b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey if (!newMeteredIfaces.contains(iface)) { 779b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey removeInterfaceQuota(iface); 78050fd36d7c38c40b087c8f3e3172478abe0c051d9Ashish Sharma } 78150fd36d7c38c40b087c8f3e3172478abe0c051d9Ashish Sharma } 782b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey mMeteredIfaces = newMeteredIfaces; 783b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey 784b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey final String[] meteredIfaces = mMeteredIfaces.toArray(new String[mMeteredIfaces.size()]); 785b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey mHandler.obtainMessage(MSG_METERED_IFACES_CHANGED, meteredIfaces).sendToTarget(); 78650fd36d7c38c40b087c8f3e3172478abe0c051d9Ashish Sharma } 78750fd36d7c38c40b087c8f3e3172478abe0c051d9Ashish Sharma 78822c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey /** 78922c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey * Once any {@link #mNetworkPolicy} are loaded from disk, ensure that we 79022c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey * have at least a default mobile policy defined. 79122c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey */ 79222c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey private void ensureActiveMobilePolicyLocked() { 79322c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey if (LOGV) Slog.v(TAG, "ensureActiveMobilePolicyLocked()"); 79422c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey final String subscriberId = getActiveSubscriberId(); 7951b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey final NetworkIdentity probeIdent = new NetworkIdentity( 7965dc0c26cffbbc62ff84f9f4c8a451e68e2c05d2dJeff Sharkey TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, false); 79722c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey 79822c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey // examine to see if any policy is defined for active mobile 79922c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey boolean mobileDefined = false; 80041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey for (NetworkPolicy policy : mNetworkPolicy.values()) { 8011b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey if (policy.template.matches(probeIdent)) { 80222c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey mobileDefined = true; 80321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 80422c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey } 80521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 80622c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey if (!mobileDefined) { 80722c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey Slog.i(TAG, "no policy for active mobile network; generating default policy"); 80821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 80902e21d6a5b5117d494777a36783909854854f751Jeff Sharkey // build default mobile policy, and assume usage cycle starts today 81002e21d6a5b5117d494777a36783909854854f751Jeff Sharkey final long warningBytes = mContext.getResources().getInteger( 81102e21d6a5b5117d494777a36783909854854f751Jeff Sharkey com.android.internal.R.integer.config_networkPolicyDefaultWarning) 81202e21d6a5b5117d494777a36783909854854f751Jeff Sharkey * MB_IN_BYTES; 81322c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey 81422c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey final Time time = new Time(Time.TIMEZONE_UTC); 81522c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey time.setToNow(); 81622c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey final int cycleDay = time.monthDay; 81722c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey 8184e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey final NetworkTemplate template = buildTemplateMobileAll(subscriberId); 81941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey mNetworkPolicy.put(template, new NetworkPolicy( 82041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey template, cycleDay, warningBytes, LIMIT_DISABLED, SNOOZE_NEVER)); 821fcc79771f092f34505b1accb80365cbcaa379667Jeff Sharkey writePolicyLocked(); 82221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 82321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 82421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 82521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private void readPolicyLocked() { 82622c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey if (LOGV) Slog.v(TAG, "readPolicyLocked()"); 82721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 82821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey // clear any existing policy and read from disk 82922c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey mNetworkPolicy.clear(); 83021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey mUidPolicy.clear(); 83121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 83221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey FileInputStream fis = null; 83321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey try { 83421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey fis = mPolicyFile.openRead(); 83521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final XmlPullParser in = Xml.newPullParser(); 83621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey in.setInput(fis, null); 83721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 83821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey int type; 83941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey int version = VERSION_INIT; 84021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey while ((type = in.next()) != END_DOCUMENT) { 84121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final String tag = in.getName(); 84221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey if (type == START_TAG) { 84321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey if (TAG_POLICY_LIST.equals(tag)) { 84421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey version = readIntAttribute(in, ATTR_VERSION); 84521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 84621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } else if (TAG_NETWORK_POLICY.equals(tag)) { 84721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final int networkTemplate = readIntAttribute(in, ATTR_NETWORK_TEMPLATE); 84821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final String subscriberId = in.getAttributeValue(null, ATTR_SUBSCRIBER_ID); 84921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final int cycleDay = readIntAttribute(in, ATTR_CYCLE_DAY); 85021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final long warningBytes = readLongAttribute(in, ATTR_WARNING_BYTES); 85121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final long limitBytes = readLongAttribute(in, ATTR_LIMIT_BYTES); 85241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey final long lastSnooze; 85341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey if (version >= VERSION_ADDED_SNOOZE) { 85441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey lastSnooze = readLongAttribute(in, ATTR_LAST_SNOOZE); 85541ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey } else { 85641ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey lastSnooze = SNOOZE_NEVER; 85741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey } 85821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 8591b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey final NetworkTemplate template = new NetworkTemplate( 8601b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey networkTemplate, subscriberId); 86141ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey mNetworkPolicy.put(template, new NetworkPolicy( 86241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey template, cycleDay, warningBytes, limitBytes, lastSnooze)); 86321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 86421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } else if (TAG_UID_POLICY.equals(tag)) { 86521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final int uid = readIntAttribute(in, ATTR_UID); 86621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final int policy = readIntAttribute(in, ATTR_POLICY); 86721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 868497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey if (isUidValidForPolicy(mContext, uid)) { 869497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey setUidPolicyUnchecked(uid, policy, false); 870497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey } else { 871497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey Slog.w(TAG, "unable to apply policy to UID " + uid + "; ignoring"); 872497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey } 87321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 87421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 87521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 87621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 87721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } catch (FileNotFoundException e) { 87821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey // missing policy is okay, probably first boot 87921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } catch (IOException e) { 88021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey Slog.e(TAG, "problem reading network stats", e); 88121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } catch (XmlPullParserException e) { 88221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey Slog.e(TAG, "problem reading network stats", e); 88321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } finally { 88421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey IoUtils.closeQuietly(fis); 88521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 88621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 88721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 88821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private void writePolicyLocked() { 88922c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey if (LOGV) Slog.v(TAG, "writePolicyLocked()"); 89021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 89121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey FileOutputStream fos = null; 89221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey try { 89321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey fos = mPolicyFile.startWrite(); 89421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 89521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey XmlSerializer out = new FastXmlSerializer(); 89621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey out.setOutput(fos, "utf-8"); 89721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey out.startDocument(null, true); 89821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 89921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey out.startTag(null, TAG_POLICY_LIST); 90041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey writeIntAttribute(out, ATTR_VERSION, VERSION_ADDED_SNOOZE); 90121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 90221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey // write all known network policies 90341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey for (NetworkPolicy policy : mNetworkPolicy.values()) { 9041b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey final NetworkTemplate template = policy.template; 9051b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey 90621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey out.startTag(null, TAG_NETWORK_POLICY); 9071b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey writeIntAttribute(out, ATTR_NETWORK_TEMPLATE, template.getMatchRule()); 9081b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey final String subscriberId = template.getSubscriberId(); 9091b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey if (subscriberId != null) { 9101b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey out.attribute(null, ATTR_SUBSCRIBER_ID, subscriberId); 91121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 91221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey writeIntAttribute(out, ATTR_CYCLE_DAY, policy.cycleDay); 91321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey writeLongAttribute(out, ATTR_WARNING_BYTES, policy.warningBytes); 91421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey writeLongAttribute(out, ATTR_LIMIT_BYTES, policy.limitBytes); 91541ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey writeLongAttribute(out, ATTR_LAST_SNOOZE, policy.lastSnooze); 91621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey out.endTag(null, TAG_NETWORK_POLICY); 91721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 91821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 91921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey // write all known uid policies 92021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey for (int i = 0; i < mUidPolicy.size(); i++) { 92121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final int uid = mUidPolicy.keyAt(i); 92221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final int policy = mUidPolicy.valueAt(i); 92321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 924497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey // skip writing empty policies 925497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey if (policy == POLICY_NONE) continue; 926497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey 92721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey out.startTag(null, TAG_UID_POLICY); 92821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey writeIntAttribute(out, ATTR_UID, uid); 92921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey writeIntAttribute(out, ATTR_POLICY, policy); 93021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey out.endTag(null, TAG_UID_POLICY); 93121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 93221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 93321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey out.endTag(null, TAG_POLICY_LIST); 93421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey out.endDocument(); 93521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 93621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey mPolicyFile.finishWrite(fos); 93721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } catch (IOException e) { 93821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey if (fos != null) { 93921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey mPolicyFile.failWrite(fos); 94021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 94121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 94221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 94321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 944d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey @Override 945d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey public void setUidPolicy(int uid, int policy) { 94621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 947a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey 948497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey if (!isUidValidForPolicy(mContext, uid)) { 949497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey throw new IllegalArgumentException("cannot apply policy to UID " + uid); 950497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey } 951497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey 952497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey setUidPolicyUnchecked(uid, policy, true); 953497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey } 954497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey 955497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey private void setUidPolicyUnchecked(int uid, int policy, boolean persist) { 956c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey final int oldPolicy; 957a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey synchronized (mRulesLock) { 958c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey oldPolicy = getUidPolicy(uid); 959a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey mUidPolicy.put(uid, policy); 960c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey 96121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey // uid policy changed, recompute rules and persist policy. 96221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey updateRulesForUidLocked(uid); 963497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey if (persist) { 964497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey writePolicyLocked(); 965497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey } 96621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 967d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey } 968d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 969d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey @Override 970d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey public int getUidPolicy(int uid) { 97121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 97221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 973a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey synchronized (mRulesLock) { 974a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey return mUidPolicy.get(uid, POLICY_NONE); 975a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 976d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey } 977d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 978c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey @Override 979c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey public void registerListener(INetworkPolicyListener listener) { 9801a303953589fdddf21d88b8fa660136f5b060d0dJeff Sharkey // TODO: create permission for observing network policy 9811a303953589fdddf21d88b8fa660136f5b060d0dJeff Sharkey mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 9821a303953589fdddf21d88b8fa660136f5b060d0dJeff Sharkey 983c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey mListeners.register(listener); 984c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey 9854414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey // TODO: consider dispatching existing rules to new listeners 986c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey } 987c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey 988c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey @Override 989c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey public void unregisterListener(INetworkPolicyListener listener) { 9901a303953589fdddf21d88b8fa660136f5b060d0dJeff Sharkey // TODO: create permission for observing network policy 9911a303953589fdddf21d88b8fa660136f5b060d0dJeff Sharkey mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 9921a303953589fdddf21d88b8fa660136f5b060d0dJeff Sharkey 993c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey mListeners.unregister(listener); 994c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey } 995c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey 9961b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey @Override 99722c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey public void setNetworkPolicies(NetworkPolicy[] policies) { 99821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 99921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 100021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey synchronized (mRulesLock) { 100122c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey mNetworkPolicy.clear(); 100222c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey for (NetworkPolicy policy : policies) { 100341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey mNetworkPolicy.put(policy.template, policy); 100422c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey } 100521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 100602e21d6a5b5117d494777a36783909854854f751Jeff Sharkey updateNetworkRulesLocked(); 1007497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey updateNotificationsLocked(); 100821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey writePolicyLocked(); 100921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 101021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 101121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 101221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey @Override 101322c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey public NetworkPolicy[] getNetworkPolicies() { 101421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 101522c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, TAG); 101621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 101721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey synchronized (mRulesLock) { 101841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey return mNetworkPolicy.values().toArray(new NetworkPolicy[mNetworkPolicy.size()]); 101941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey } 102041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey } 102141ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey 102241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey @Override 102341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey public void snoozePolicy(NetworkTemplate template) { 102441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 102541ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey 102641ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey // try refreshing time source when stale 102741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey if (mTime.getCacheAge() > TIME_CACHE_MAX_AGE) { 102841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey mTime.forceRefresh(); 102941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey } 103041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey 103141ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey final long currentTime = mTime.hasCache() ? mTime.currentTimeMillis() 103241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey : System.currentTimeMillis(); 103341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey 103441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey synchronized (mRulesLock) { 103541ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey // find and snooze local policy that matches 103641ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey final NetworkPolicy policy = mNetworkPolicy.get(template); 103741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey if (policy == null) { 103841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey throw new IllegalArgumentException("unable to find policy for " + template); 103941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey } 104041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey 104141ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey policy.lastSnooze = currentTime; 104241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey 104341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey updateNetworkRulesLocked(); 104441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey updateNotificationsLocked(); 104541ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey writePolicyLocked(); 104621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 104721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 104821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 104921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey @Override 10501b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) { 105175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey mContext.enforceCallingOrSelfPermission(DUMP, TAG); 10521b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey 105341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey final HashSet<String> argSet = new HashSet<String>(); 105441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey for (String arg : args) { 105541ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey argSet.add(arg); 105641ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey } 105741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey 10581b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey synchronized (mRulesLock) { 105941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey if (argSet.contains("unsnooze")) { 106041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey for (NetworkPolicy policy : mNetworkPolicy.values()) { 106141ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey policy.lastSnooze = SNOOZE_NEVER; 106241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey } 106341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey writePolicyLocked(); 106441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey fout.println("Wiped snooze timestamps"); 106541ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey return; 106641ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey } 106741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey 106821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey fout.println("Network policies:"); 106941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey for (NetworkPolicy policy : mNetworkPolicy.values()) { 107022c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey fout.print(" "); fout.println(policy.toString()); 107121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 107221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 10731b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey fout.println("Policy status for known UIDs:"); 10741b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey 10751b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey final SparseBooleanArray knownUids = new SparseBooleanArray(); 10761b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey collectKeys(mUidPolicy, knownUids); 10771b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey collectKeys(mUidForeground, knownUids); 10781b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey collectKeys(mUidRules, knownUids); 10791b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey 10801b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey final int size = knownUids.size(); 10811b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey for (int i = 0; i < size; i++) { 10821b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey final int uid = knownUids.keyAt(i); 10831b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey fout.print(" UID="); 10841b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey fout.print(uid); 10851b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey 10861b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey fout.print(" policy="); 10871b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey final int policyIndex = mUidPolicy.indexOfKey(uid); 10881b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey if (policyIndex < 0) { 10891b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey fout.print("UNKNOWN"); 10901b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } else { 10911b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey dumpPolicy(fout, mUidPolicy.valueAt(policyIndex)); 10921b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } 10931b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey 10941b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey fout.print(" foreground="); 10951b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey final int foregroundIndex = mUidPidForeground.indexOfKey(uid); 10961b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey if (foregroundIndex < 0) { 10971b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey fout.print("UNKNOWN"); 10981b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } else { 10991b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey dumpSparseBooleanArray(fout, mUidPidForeground.valueAt(foregroundIndex)); 11001b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } 11011b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey 11021b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey fout.print(" rules="); 11031b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey final int rulesIndex = mUidRules.indexOfKey(uid); 11041b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey if (rulesIndex < 0) { 11051b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey fout.print("UNKNOWN"); 11061b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } else { 11071b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey dumpRules(fout, mUidRules.valueAt(rulesIndex)); 11081b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } 11091b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey 11101b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey fout.println(); 11111b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } 11121b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } 11131b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } 11149599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey 11159599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey @Override 11169599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey public boolean isUidForeground(int uid) { 1117497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 1118497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey 11199599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey synchronized (mRulesLock) { 11209599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey // only really in foreground when screen is also on 11219599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey return mUidForeground.get(uid, false) && mScreenOn; 11229599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey } 1123c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey } 1124c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey 1125d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey /** 1126d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey * Foreground for PID changed; recompute foreground at UID level. If 112721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey * changed, will trigger {@link #updateRulesForUidLocked(int)}. 1128d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey */ 112921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private void computeUidForegroundLocked(int uid) { 1130d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey final SparseBooleanArray pidForeground = mUidPidForeground.get(uid); 1131d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 1132d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey // current pid is dropping foreground; examine other pids 1133d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey boolean uidForeground = false; 1134d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey final int size = pidForeground.size(); 1135d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey for (int i = 0; i < size; i++) { 1136d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey if (pidForeground.valueAt(i)) { 1137d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey uidForeground = true; 1138d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey break; 1139d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey } 1140d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey } 1141d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 1142d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey final boolean oldUidForeground = mUidForeground.get(uid, false); 1143d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey if (oldUidForeground != uidForeground) { 1144d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey // foreground changed, push updated rules 1145d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey mUidForeground.put(uid, uidForeground); 114621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey updateRulesForUidLocked(uid); 1147a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 1148a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 1149a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey 1150a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey private void updateScreenOn() { 1151a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey synchronized (mRulesLock) { 1152a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey try { 1153a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey mScreenOn = mPowerManager.isScreenOn(); 1154a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } catch (RemoteException e) { 1155a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 115621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey updateRulesForScreenLocked(); 1157d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey } 1158d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey } 1159d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 1160b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey private void updateBackgroundData(boolean systemReady) { 1161b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey synchronized (mRulesLock) { 1162b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey try { 1163b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey mBackgroundData = mConnManager.getBackgroundDataSetting(); 1164b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey } catch (RemoteException e) { 1165b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey } 1166b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey if (systemReady && mBackgroundData) { 1167b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey // typical behavior of background enabled during systemReady; 1168b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey // no need to clear rules for all UIDs. 1169b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey } else { 1170b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey updateRulesForBackgroundDataLocked(); 1171b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey } 1172b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey } 1173b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey } 1174b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey 1175a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey /** 1176a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey * Update rules that might be changed by {@link #mScreenOn} value. 1177a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey */ 117821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private void updateRulesForScreenLocked() { 1179a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey // only update rules for anyone with foreground activities 1180a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey final int size = mUidForeground.size(); 1181a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey for (int i = 0; i < size; i++) { 1182a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey if (mUidForeground.valueAt(i)) { 1183a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey final int uid = mUidForeground.keyAt(i); 118421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey updateRulesForUidLocked(uid); 1185a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 1186a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 1187a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 1188a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey 1189b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey /** 1190b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey * Update rules that might be changed by {@link #mBackgroundData} value. 1191b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey */ 1192b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey private void updateRulesForBackgroundDataLocked() { 1193b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey // update rules for all installed applications 1194b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey final PackageManager pm = mContext.getPackageManager(); 1195b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey final List<ApplicationInfo> apps = pm.getInstalledApplications(0); 1196b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey for (ApplicationInfo app : apps) { 1197b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey updateRulesForUidLocked(app.uid); 1198b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey } 1199b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey 1200b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey // and catch system UIDs 1201b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey // TODO: keep in sync with android_filesystem_config.h 1202b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey for (int uid = 1000; uid <= 1025; uid++) { 1203b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey updateRulesForUidLocked(uid); 1204b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey } 1205b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey for (int uid = 2000; uid <= 2002; uid++) { 1206b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey updateRulesForUidLocked(uid); 1207b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey } 1208b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey for (int uid = 3000; uid <= 3007; uid++) { 1209b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey updateRulesForUidLocked(uid); 1210b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey } 1211b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey for (int uid = 9998; uid <= 9999; uid++) { 1212b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey updateRulesForUidLocked(uid); 1213b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey } 1214b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey } 1215b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey 121621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private void updateRulesForUidLocked(int uid) { 1217d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey final int uidPolicy = getUidPolicy(uid); 12189599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey final boolean uidForeground = isUidForeground(uid); 1219d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 1220c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey // derive active rules based on policy and active state 1221c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey int uidRules = RULE_ALLOW_ALL; 1222fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey if (!uidForeground && (uidPolicy & POLICY_REJECT_METERED_BACKGROUND) != 0) { 1223fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey // uid in background, and policy says to block metered data 1224fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey uidRules = RULE_REJECT_METERED; 1225d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey } 1226b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey if (!uidForeground && !mBackgroundData) { 1227b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey // uid in background, and global background disabled 1228b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey uidRules = RULE_REJECT_METERED; 1229b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey } 1230d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 1231c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey // TODO: only dispatch when rules actually change 1232c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey 1233350083e36b9db6062e165954403ef921ff3dfdadJeff Sharkey if (uidRules == RULE_ALLOW_ALL) { 1234350083e36b9db6062e165954403ef921ff3dfdadJeff Sharkey mUidRules.delete(uid); 1235350083e36b9db6062e165954403ef921ff3dfdadJeff Sharkey } else { 1236350083e36b9db6062e165954403ef921ff3dfdadJeff Sharkey mUidRules.put(uid, uidRules); 1237350083e36b9db6062e165954403ef921ff3dfdadJeff Sharkey } 1238c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey 1239fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey final boolean rejectMetered = (uidRules & RULE_REJECT_METERED) != 0; 124050fd36d7c38c40b087c8f3e3172478abe0c051d9Ashish Sharma setUidNetworkRules(uid, rejectMetered); 1241497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey 1242c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey // dispatch changed rule to existing listeners 12434414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey mHandler.obtainMessage(MSG_RULES_CHANGED, uid, uidRules).sendToTarget(); 12444414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey } 12454414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey 12464414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey private Handler.Callback mHandlerCallback = new Handler.Callback() { 12474414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey /** {@inheritDoc} */ 12484414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey public boolean handleMessage(Message msg) { 12494414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey switch (msg.what) { 12504414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey case MSG_RULES_CHANGED: { 12514414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey final int uid = msg.arg1; 12524414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey final int uidRules = msg.arg2; 12534414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey final int length = mListeners.beginBroadcast(); 12544414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey for (int i = 0; i < length; i++) { 12554414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey final INetworkPolicyListener listener = mListeners.getBroadcastItem(i); 12564414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey if (listener != null) { 12574414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey try { 12584414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey listener.onUidRulesChanged(uid, uidRules); 12594414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey } catch (RemoteException e) { 12604414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey } 12614414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey } 12624414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey } 12634414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey mListeners.finishBroadcast(); 12644414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey return true; 12654414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey } 12664414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey case MSG_METERED_IFACES_CHANGED: { 12674414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey final String[] meteredIfaces = (String[]) msg.obj; 12684414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey final int length = mListeners.beginBroadcast(); 12694414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey for (int i = 0; i < length; i++) { 12704414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey final INetworkPolicyListener listener = mListeners.getBroadcastItem(i); 12714414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey if (listener != null) { 12724414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey try { 12734414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey listener.onMeteredIfacesChanged(meteredIfaces); 12744414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey } catch (RemoteException e) { 12754414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey } 12764414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey } 12774414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey } 12784414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey mListeners.finishBroadcast(); 12794414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey return true; 12804414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey } 12814414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey default: { 12824414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey return false; 1283af11d4859582a9736aa204562f0beac5a7d60934Jeff Sharkey } 1284af11d4859582a9736aa204562f0beac5a7d60934Jeff Sharkey } 1285af11d4859582a9736aa204562f0beac5a7d60934Jeff Sharkey } 12864414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey }; 128722c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey 128841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey private void setInterfaceQuota(String iface, long quotaBytes) { 1289b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey try { 129041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey mNetworkManager.setInterfaceQuota(iface, quotaBytes); 1291b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey } catch (IllegalStateException e) { 1292b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey Slog.e(TAG, "problem setting interface quota", e); 1293b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey } catch (RemoteException e) { 1294b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey Slog.e(TAG, "problem setting interface quota", e); 1295b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey } 1296b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey } 1297b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey 1298b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey private void removeInterfaceQuota(String iface) { 1299b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey try { 130041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey mNetworkManager.removeInterfaceQuota(iface); 1301b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey } catch (IllegalStateException e) { 1302b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey Slog.e(TAG, "problem removing interface quota", e); 1303b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey } catch (RemoteException e) { 1304b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey Slog.e(TAG, "problem removing interface quota", e); 1305b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey } 1306b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey } 1307b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey 130841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey private void setInterfaceAlert(String iface, long alertBytes) { 130941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey try { 131041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey mNetworkManager.setInterfaceAlert(iface, alertBytes); 131141ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey } catch (IllegalStateException e) { 131241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey Slog.e(TAG, "problem setting interface alert", e); 131341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey } catch (RemoteException e) { 131441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey Slog.e(TAG, "problem setting interface alert", e); 131541ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey } 131641ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey } 131741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey 131841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey private void removeInterfaceAlert(String iface) { 131941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey try { 132041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey mNetworkManager.removeInterfaceAlert(iface); 132141ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey } catch (IllegalStateException e) { 132241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey Slog.e(TAG, "problem removing interface alert", e); 132341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey } catch (RemoteException e) { 132441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey Slog.e(TAG, "problem removing interface alert", e); 132541ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey } 132641ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey } 132741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey 1328b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey private void setUidNetworkRules(int uid, boolean rejectOnQuotaInterfaces) { 1329b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey try { 133041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey mNetworkManager.setUidNetworkRules(uid, rejectOnQuotaInterfaces); 1331b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey } catch (IllegalStateException e) { 1332b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey Slog.e(TAG, "problem setting uid rules", e); 1333b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey } catch (RemoteException e) { 1334b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey Slog.e(TAG, "problem setting uid rules", e); 1335b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey } 1336b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey } 1337b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey 133822c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey private String getActiveSubscriberId() { 133922c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey final TelephonyManager telephony = (TelephonyManager) mContext.getSystemService( 134022c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey Context.TELEPHONY_SERVICE); 134122c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey return telephony.getSubscriberId(); 134222c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey } 134322c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey 134441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey private static Intent buildNetworkOverLimitIntent(NetworkTemplate template) { 134541ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey final Intent intent = new Intent(); 134641ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey intent.setComponent(new ComponentName( 134741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey "com.android.systemui", "com.android.systemui.net.NetworkOverLimitActivity")); 134841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 134941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey intent.putExtra(EXTRA_NETWORK_TEMPLATE, template); 135041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey return intent; 135141ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey } 135241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey 135341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey private static Intent buildViewDataUsageIntent(NetworkTemplate template) { 135441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey final Intent intent = new Intent(); 135541ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey intent.setComponent(new ComponentName( 135641ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey "com.android.settings", "com.android.settings.Settings$DataUsageSummaryActivity")); 135741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 135841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey intent.putExtra(EXTRA_NETWORK_TEMPLATE, template); 135941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey return intent; 136041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey } 136141ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey 13621b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey private static void collectKeys(SparseIntArray source, SparseBooleanArray target) { 13631b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey final int size = source.size(); 13641b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey for (int i = 0; i < size; i++) { 13651b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey target.put(source.keyAt(i), true); 13661b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } 13671b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } 13681b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey 13691b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey private static void collectKeys(SparseBooleanArray source, SparseBooleanArray target) { 13701b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey final int size = source.size(); 13711b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey for (int i = 0; i < size; i++) { 13721b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey target.put(source.keyAt(i), true); 13731b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } 13741b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } 13751b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey 13761b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey private static void dumpSparseBooleanArray(PrintWriter fout, SparseBooleanArray value) { 13771b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey fout.print("["); 13781b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey final int size = value.size(); 13791b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey for (int i = 0; i < size; i++) { 13801b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey fout.print(value.keyAt(i) + "=" + value.valueAt(i)); 13811b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey if (i < size - 1) fout.print(","); 13821b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } 13831b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey fout.print("]"); 13841b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } 138521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 138621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private static int readIntAttribute(XmlPullParser in, String name) throws IOException { 138721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final String value = in.getAttributeValue(null, name); 138821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey try { 138921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey return Integer.parseInt(value); 139021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } catch (NumberFormatException e) { 139121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey throw new ProtocolException("problem parsing " + name + "=" + value + " as int"); 139221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 139321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 139421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 139521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private static long readLongAttribute(XmlPullParser in, String name) throws IOException { 139621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final String value = in.getAttributeValue(null, name); 139721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey try { 139821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey return Long.parseLong(value); 139921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } catch (NumberFormatException e) { 140041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey throw new ProtocolException("problem parsing " + name + "=" + value + " as long"); 140121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 140221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 140321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 140421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private static void writeIntAttribute(XmlSerializer out, String name, int value) 140521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey throws IOException { 140621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey out.attribute(null, name, Integer.toString(value)); 140721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 140821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 140921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private static void writeLongAttribute(XmlSerializer out, String name, long value) 141021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey throws IOException { 141121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey out.attribute(null, name, Long.toString(value)); 141221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 141321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 1414d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey} 1415