NetworkPolicyManagerService.java revision 21c9c45e5caf62b935354b74392fb40c4bf18529
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; 2321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport static android.net.ConnectivityManager.CONNECTIVITY_ACTION; 24d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkeyimport static android.net.NetworkPolicyManager.POLICY_NONE; 25c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkeyimport static android.net.NetworkPolicyManager.POLICY_REJECT_PAID_BACKGROUND; 26c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkeyimport static android.net.NetworkPolicyManager.RULE_ALLOW_ALL; 27c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkeyimport static android.net.NetworkPolicyManager.RULE_REJECT_PAID; 281b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkeyimport static android.net.NetworkPolicyManager.dumpPolicy; 291b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkeyimport static android.net.NetworkPolicyManager.dumpRules; 3021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport static android.text.format.DateUtils.DAY_IN_MILLIS; 3121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport static android.text.format.Time.MONTH_DAY; 3221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport static com.android.internal.util.Preconditions.checkNotNull; 3321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 3421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport static org.xmlpull.v1.XmlPullParser.START_TAG; 35d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 36a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkeyimport android.app.IActivityManager; 37a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkeyimport android.app.IProcessObserver; 38a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkeyimport android.content.BroadcastReceiver; 39d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkeyimport android.content.Context; 40a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkeyimport android.content.Intent; 41a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkeyimport android.content.IntentFilter; 42c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkeyimport android.net.ConnectivityManager; 4321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport android.net.IConnectivityManager; 44c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkeyimport android.net.INetworkPolicyListener; 45d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkeyimport android.net.INetworkPolicyManager; 4675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.net.INetworkStatsService; 4721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport android.net.NetworkPolicy; 4821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport android.net.NetworkState; 4921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport android.net.NetworkStats; 5021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport android.os.Environment; 5121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport android.os.Handler; 5221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport android.os.HandlerThread; 53a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkeyimport android.os.IPowerManager; 54c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkeyimport android.os.RemoteCallbackList; 55a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkeyimport android.os.RemoteException; 5621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport android.text.format.Time; 5721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport android.util.NtpTrustedTime; 58a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkeyimport android.util.Slog; 59d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkeyimport android.util.SparseArray; 60d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkeyimport android.util.SparseBooleanArray; 61d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkeyimport android.util.SparseIntArray; 6221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport android.util.TrustedTime; 6321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport android.util.Xml; 64d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 6521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport com.android.internal.os.AtomicFile; 6621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport com.android.internal.util.FastXmlSerializer; 6721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport com.android.internal.util.Objects; 6821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport com.google.android.collect.Lists; 6921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport com.google.android.collect.Maps; 7021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 7121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport org.xmlpull.v1.XmlPullParser; 7221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport org.xmlpull.v1.XmlPullParserException; 7321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport org.xmlpull.v1.XmlSerializer; 7421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 7521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport java.io.File; 761b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkeyimport java.io.FileDescriptor; 7721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport java.io.FileInputStream; 7821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport java.io.FileNotFoundException; 7921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport java.io.FileOutputStream; 8021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport java.io.IOException; 811b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkeyimport java.io.PrintWriter; 8221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport java.net.ProtocolException; 8321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport java.util.ArrayList; 8421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport java.util.Arrays; 8521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport java.util.HashMap; 8621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 8721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport libcore.io.IoUtils; 881b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey 89d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey/** 90d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey * Service that maintains low-level network policy rules and collects usage 91d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey * statistics to drive those rules. 92c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey * <p> 93c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey * Derives active rules by combining a given policy with other system status, 94c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey * and delivers to listeners, such as {@link ConnectivityManager}, for 95c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey * enforcement. 96d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey */ 97d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkeypublic class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { 98d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey private static final String TAG = "NetworkPolicy"; 99d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey private static final boolean LOGD = true; 100d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 10121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private static final int VERSION_CURRENT = 1; 10221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 10321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private static final String TAG_POLICY_LIST = "policy-list"; 10421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private static final String TAG_NETWORK_POLICY = "network-policy"; 10521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private static final String TAG_UID_POLICY = "uid-policy"; 10621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 10721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private static final String ATTR_VERSION = "version"; 10821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private static final String ATTR_NETWORK_TEMPLATE = "networkTemplate"; 10921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private static final String ATTR_SUBSCRIBER_ID = "subscriberId"; 11021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private static final String ATTR_CYCLE_DAY = "cycleDay"; 11121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private static final String ATTR_WARNING_BYTES = "warningBytes"; 11221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private static final String ATTR_LIMIT_BYTES = "limitBytes"; 11321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private static final String ATTR_UID = "uid"; 11421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private static final String ATTR_POLICY = "policy"; 11521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 11621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private static final long TIME_CACHE_MAX_AGE = DAY_IN_MILLIS; 11721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 11875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey private final Context mContext; 11975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey private final IActivityManager mActivityManager; 12075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey private final IPowerManager mPowerManager; 12175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey private final INetworkStatsService mNetworkStats; 12221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private final TrustedTime mTime; 12321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 12421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private IConnectivityManager mConnManager; 125a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey 12675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey private final Object mRulesLock = new Object(); 127a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey 128c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey private boolean mScreenOn; 129d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 130d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey /** Current network policy for each UID. */ 131a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey private SparseIntArray mUidPolicy = new SparseIntArray(); 132c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey /** Current derived network rules for each UID. */ 133c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey private SparseIntArray mUidRules = new SparseIntArray(); 134d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 13521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey /** Set of policies for strong network templates. */ 13621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private HashMap<StrongTemplate, NetworkPolicy> mTemplatePolicy = Maps.newHashMap(); 13721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 138d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey /** Foreground at both UID and PID granularity. */ 139a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey private SparseBooleanArray mUidForeground = new SparseBooleanArray(); 140a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey private SparseArray<SparseBooleanArray> mUidPidForeground = new SparseArray< 141a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey SparseBooleanArray>(); 142d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 143c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey private final RemoteCallbackList<INetworkPolicyListener> mListeners = new RemoteCallbackList< 144c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey INetworkPolicyListener>(); 145c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey 14621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private final HandlerThread mHandlerThread; 14721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private final Handler mHandler; 14821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 14921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private final AtomicFile mPolicyFile; 150d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 151c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey // TODO: keep whitelist of system-critical services that should never have 152c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey // rules enforced, such as system, phone, and radio UIDs. 153c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey 154d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey // TODO: dispatch callbacks through handler when locked 155d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey 15675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey public NetworkPolicyManagerService(Context context, IActivityManager activityManager, 15775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey IPowerManager powerManager, INetworkStatsService networkStats) { 15821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey // TODO: move to using cached NtpTrustedTime 15921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey this(context, activityManager, powerManager, networkStats, new NtpTrustedTime(), 16021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey getSystemDir()); 16121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 16221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 16321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private static File getSystemDir() { 16421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey return new File(Environment.getDataDirectory(), "system"); 16521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 16621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 16721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey public NetworkPolicyManagerService(Context context, IActivityManager activityManager, 16821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey IPowerManager powerManager, INetworkStatsService networkStats, TrustedTime time, 16921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey File systemDir) { 170a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey mContext = checkNotNull(context, "missing context"); 171a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey mActivityManager = checkNotNull(activityManager, "missing activityManager"); 172a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey mPowerManager = checkNotNull(powerManager, "missing powerManager"); 17375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey mNetworkStats = checkNotNull(networkStats, "missing networkStats"); 17421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey mTime = checkNotNull(time, "missing TrustedTime"); 17521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 17621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey mHandlerThread = new HandlerThread(TAG); 17721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey mHandlerThread.start(); 17821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey mHandler = new Handler(mHandlerThread.getLooper()); 17921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 18021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey mPolicyFile = new AtomicFile(new File(systemDir, "netpolicy.xml")); 18121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 18221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 18321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey public void bindConnectivityManager(IConnectivityManager connManager) { 18421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey mConnManager = checkNotNull(connManager, "missing IConnectivityManager"); 185a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 186d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 187a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey public void systemReady() { 18821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey synchronized (mRulesLock) { 18921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey // read policy from disk 19021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey readPolicyLocked(); 19121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 192d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 193a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey updateScreenOn(); 194d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 195a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey try { 196a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey mActivityManager.registerProcessObserver(mProcessObserver); 197a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } catch (RemoteException e) { 198a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey // ouch, no foregroundActivities updates means some processes may 199a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey // never get network access. 200a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey Slog.e(TAG, "unable to register IProcessObserver", e); 201a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 202d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 203a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey // TODO: traverse existing processes to know foreground state, or have 204a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey // activitymanager dispatch current state when new observer attached. 205d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 206a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey final IntentFilter screenFilter = new IntentFilter(); 207a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey screenFilter.addAction(Intent.ACTION_SCREEN_ON); 208a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey screenFilter.addAction(Intent.ACTION_SCREEN_OFF); 209a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey mContext.registerReceiver(mScreenReceiver, screenFilter); 210d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 21121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey // watch for network interfaces to be claimed 21221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final IntentFilter ifaceFilter = new IntentFilter(); 21321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey ifaceFilter.addAction(CONNECTIVITY_ACTION); 21421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey mContext.registerReceiver(mIfaceReceiver, ifaceFilter, CONNECTIVITY_INTERNAL, mHandler); 21521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 216a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 217d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 218a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey private IProcessObserver mProcessObserver = new IProcessObserver.Stub() { 219a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey @Override 220a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey public void onForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities) { 221a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey // only someone like AMS should only be calling us 22275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey mContext.enforceCallingOrSelfPermission(MANAGE_APP_TOKENS, TAG); 223a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey 224a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey synchronized (mRulesLock) { 225a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey // because a uid can have multiple pids running inside, we need to 226a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey // remember all pid states and summarize foreground at uid level. 227a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey 228a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey // record foreground for this specific pid 229a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey SparseBooleanArray pidForeground = mUidPidForeground.get(uid); 230a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey if (pidForeground == null) { 231a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey pidForeground = new SparseBooleanArray(2); 232a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey mUidPidForeground.put(uid, pidForeground); 233a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 234a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey pidForeground.put(pid, foregroundActivities); 23521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey computeUidForegroundLocked(uid); 236a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 237d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey } 238d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 239a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey @Override 240a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey public void onProcessDied(int pid, int uid) { 241a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey // only someone like AMS should only be calling us 24275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey mContext.enforceCallingOrSelfPermission(MANAGE_APP_TOKENS, TAG); 243a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey 244a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey synchronized (mRulesLock) { 245a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey // clear records and recompute, when they exist 246a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey final SparseBooleanArray pidForeground = mUidPidForeground.get(uid); 247a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey if (pidForeground != null) { 248a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey pidForeground.delete(pid); 24921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey computeUidForegroundLocked(uid); 250a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 251a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 252a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 253a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey }; 254a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey 255a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey private BroadcastReceiver mScreenReceiver = new BroadcastReceiver() { 256a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey @Override 257a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey public void onReceive(Context context, Intent intent) { 258a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey synchronized (mRulesLock) { 259a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey // screen-related broadcasts are protected by system, no need 260a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey // for permissions check. 261a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey updateScreenOn(); 262a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 263a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 264a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey }; 265d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 26621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey /** 26721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey * Receiver that watches for {@link IConnectivityManager} to claim network 26821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey * interfaces. Used to apply {@link NetworkPolicy} when networks match 26921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey * {@link StrongTemplate}. 27021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey */ 27121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private BroadcastReceiver mIfaceReceiver = new BroadcastReceiver() { 27221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey @Override 27321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey public void onReceive(Context context, Intent intent) { 27421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey // on background handler thread, and verified CONNECTIVITY_INTERNAL 27521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey // permission above. 27621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey synchronized (mRulesLock) { 27721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey updateIfacesLocked(); 27821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 27921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 28021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey }; 28121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 28221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey /** 28321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey * Examine all connected {@link NetworkState}, looking for 28421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey * {@link NetworkPolicy} that need to be enforced. When matches found, set 28521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey * remaining quota based on usage cycle and historical stats. 28621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey */ 28721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private void updateIfacesLocked() { 28821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey if (LOGD) Slog.v(TAG, "updateIfacesLocked()"); 28921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 29021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final NetworkState[] states; 29121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey try { 29221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey states = mConnManager.getAllNetworkState(); 29321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } catch (RemoteException e) { 29421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey Slog.w(TAG, "problem reading network state"); 29521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey return; 29621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 29721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 29821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey // first, derive identity for all connected networks, which can be used 29921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey // to match against templates. 30021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final HashMap<NetworkIdentity, String> networks = Maps.newHashMap(); 30121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey for (NetworkState state : states) { 30221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey // stash identity and iface away for later use 30321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey if (state.networkInfo.isConnected()) { 30421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final String iface = state.linkProperties.getInterfaceName(); 30521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state); 30621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey networks.put(ident, iface); 30721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 30821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 30921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 31021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey // build list of rules and ifaces to enforce them against 31121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final HashMap<StrongTemplate, String[]> rules = Maps.newHashMap(); 31221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final ArrayList<String> ifaceList = Lists.newArrayList(); 31321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey for (StrongTemplate template : mTemplatePolicy.keySet()) { 31421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 31521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey // collect all active ifaces that match this template 31621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey ifaceList.clear(); 31721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey for (NetworkIdentity ident : networks.keySet()) { 31821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey if (ident.matchesTemplate(template.networkTemplate, template.subscriberId)) { 31921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final String iface = networks.get(ident); 32021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey ifaceList.add(iface); 32121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 32221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 32321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 32421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey if (ifaceList.size() > 0) { 32521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final String[] ifaces = ifaceList.toArray(new String[ifaceList.size()]); 32621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey rules.put(template, ifaces); 32721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 32821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 32921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 33021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey // try refreshing time source when stale 33121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey if (mTime.getCacheAge() > TIME_CACHE_MAX_AGE) { 33221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey mTime.forceRefresh(); 33321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 33421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 33521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final long currentTime = mTime.hasCache() ? mTime.currentTimeMillis() 33621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey : System.currentTimeMillis(); 33721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 33821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey // apply each policy that we found ifaces for; compute remaining data 33921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey // based on current cycle and historical stats, and push to kernel. 34021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey for (StrongTemplate template : rules.keySet()) { 34121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final NetworkPolicy policy = mTemplatePolicy.get(template); 34221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final String[] ifaces = rules.get(policy); 34321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 34421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final long start = computeLastCycleBoundary(currentTime, policy); 34521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final long end = currentTime; 34621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 34721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final NetworkStats stats; 34821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey try { 34921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey stats = mNetworkStats.getSummaryForNetwork( 35021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey start, end, template.networkTemplate, template.subscriberId); 35121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } catch (RemoteException e) { 35221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey Slog.w(TAG, "problem reading summary for template " + template.networkTemplate); 35321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey continue; 35421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 35521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 35621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey // remaining "quota" is based on usage in current cycle 35721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final long total = stats.rx[0] + stats.tx[0]; 35821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final long quota = Math.max(0, policy.limitBytes - total); 35921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 36021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey if (LOGD) { 36121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey Slog.d(TAG, "applying policy " + policy.toString() + " to ifaces " 36221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey + Arrays.toString(ifaces) + " with quota " + quota); 36321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 36421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 36521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey // TODO: push rule down through NetworkManagementService.setInterfaceQuota() 36621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 36721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 36821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 36921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 37021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey /** 37121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey * Compute the last cycle boundary for the given {@link NetworkPolicy}. For 37221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey * example, if cycle day is 20th, and today is June 15th, it will return May 37321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey * 20th. When cycle day doesn't exist in current month, it snaps to the 1st 37421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey * of following month. 37521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey */ 37621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey // @VisibleForTesting 37721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey public static long computeLastCycleBoundary(long currentTime, NetworkPolicy policy) { 37821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final Time now = new Time(Time.TIMEZONE_UTC); 37921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey now.set(currentTime); 38021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 38121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey // first, find cycle boundary for current month 38221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final Time cycle = new Time(now); 38321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey cycle.hour = cycle.minute = cycle.second = 0; 38421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey snapToCycleDay(cycle, policy.cycleDay); 38521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 38621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey if (cycle.after(now)) { 38721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey // cycle boundary is beyond now, use last cycle boundary; start by 38821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey // pushing ourselves squarely into last month. 38921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final Time lastMonth = new Time(now); 39021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey lastMonth.hour = lastMonth.minute = lastMonth.second = 0; 39121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey lastMonth.monthDay = 1; 39221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey lastMonth.month -= 1; 39321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey lastMonth.normalize(true); 39421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 39521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey cycle.set(lastMonth); 39621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey snapToCycleDay(cycle, policy.cycleDay); 39721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 39821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 39921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey return cycle.toMillis(true); 40021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 40121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 40221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey /** 40321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey * Snap to the cycle day for the current month given; when cycle day doesn't 40421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey * exist, it snaps to 1st of following month. 40521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey */ 40621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private static void snapToCycleDay(Time time, int cycleDay) { 40721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey if (cycleDay > time.getActualMaximum(MONTH_DAY)) { 40821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey // cycle day isn't valid this month; snap to 1st of next month 40921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey time.month += 1; 41021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey time.monthDay = 1; 41121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } else { 41221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey time.monthDay = cycleDay; 41321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 41421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey time.normalize(true); 41521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 41621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 41721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private void readPolicyLocked() { 41821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey if (LOGD) Slog.v(TAG, "readPolicyLocked()"); 41921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 42021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey // clear any existing policy and read from disk 42121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey mTemplatePolicy.clear(); 42221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey mUidPolicy.clear(); 42321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 42421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey FileInputStream fis = null; 42521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey try { 42621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey fis = mPolicyFile.openRead(); 42721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final XmlPullParser in = Xml.newPullParser(); 42821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey in.setInput(fis, null); 42921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 43021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey int type; 43121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey int version = VERSION_CURRENT; 43221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey while ((type = in.next()) != END_DOCUMENT) { 43321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final String tag = in.getName(); 43421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey if (type == START_TAG) { 43521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey if (TAG_POLICY_LIST.equals(tag)) { 43621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey version = readIntAttribute(in, ATTR_VERSION); 43721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 43821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } else if (TAG_NETWORK_POLICY.equals(tag)) { 43921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final int networkTemplate = readIntAttribute(in, ATTR_NETWORK_TEMPLATE); 44021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final String subscriberId = in.getAttributeValue(null, ATTR_SUBSCRIBER_ID); 44121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 44221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final int cycleDay = readIntAttribute(in, ATTR_CYCLE_DAY); 44321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final long warningBytes = readLongAttribute(in, ATTR_WARNING_BYTES); 44421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final long limitBytes = readLongAttribute(in, ATTR_LIMIT_BYTES); 44521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 44621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey mTemplatePolicy.put(new StrongTemplate(networkTemplate, subscriberId), 44721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey new NetworkPolicy(cycleDay, warningBytes, limitBytes)); 44821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 44921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } else if (TAG_UID_POLICY.equals(tag)) { 45021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final int uid = readIntAttribute(in, ATTR_UID); 45121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final int policy = readIntAttribute(in, ATTR_POLICY); 45221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 45321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey mUidPolicy.put(uid, policy); 45421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 45521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 45621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 45721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 45821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } catch (FileNotFoundException e) { 45921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey // missing policy is okay, probably first boot 46021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } catch (IOException e) { 46121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey Slog.e(TAG, "problem reading network stats", e); 46221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } catch (XmlPullParserException e) { 46321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey Slog.e(TAG, "problem reading network stats", e); 46421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } finally { 46521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey IoUtils.closeQuietly(fis); 46621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 46721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 46821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 46921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private void writePolicyLocked() { 47021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey if (LOGD) Slog.v(TAG, "writePolicyLocked()"); 47121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 47221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey FileOutputStream fos = null; 47321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey try { 47421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey fos = mPolicyFile.startWrite(); 47521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 47621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey XmlSerializer out = new FastXmlSerializer(); 47721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey out.setOutput(fos, "utf-8"); 47821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey out.startDocument(null, true); 47921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 48021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey out.startTag(null, TAG_POLICY_LIST); 48121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey writeIntAttribute(out, ATTR_VERSION, VERSION_CURRENT); 48221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 48321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey // write all known network policies 48421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey for (StrongTemplate template : mTemplatePolicy.keySet()) { 48521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final NetworkPolicy policy = mTemplatePolicy.get(template); 48621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 48721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey out.startTag(null, TAG_NETWORK_POLICY); 48821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey writeIntAttribute(out, ATTR_NETWORK_TEMPLATE, template.networkTemplate); 48921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey if (template.subscriberId != null) { 49021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey out.attribute(null, ATTR_SUBSCRIBER_ID, template.subscriberId); 49121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 49221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey writeIntAttribute(out, ATTR_CYCLE_DAY, policy.cycleDay); 49321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey writeLongAttribute(out, ATTR_WARNING_BYTES, policy.warningBytes); 49421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey writeLongAttribute(out, ATTR_LIMIT_BYTES, policy.limitBytes); 49521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey out.endTag(null, TAG_NETWORK_POLICY); 49621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 49721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 49821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey // write all known uid policies 49921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey for (int i = 0; i < mUidPolicy.size(); i++) { 50021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final int uid = mUidPolicy.keyAt(i); 50121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final int policy = mUidPolicy.valueAt(i); 50221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 50321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey out.startTag(null, TAG_UID_POLICY); 50421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey writeIntAttribute(out, ATTR_UID, uid); 50521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey writeIntAttribute(out, ATTR_POLICY, policy); 50621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey out.endTag(null, TAG_UID_POLICY); 50721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 50821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 50921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey out.endTag(null, TAG_POLICY_LIST); 51021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey out.endDocument(); 51121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 51221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey mPolicyFile.finishWrite(fos); 51321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } catch (IOException e) { 51421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey if (fos != null) { 51521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey mPolicyFile.failWrite(fos); 51621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 51721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 51821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 51921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 520d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey @Override 521d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey public void setUidPolicy(int uid, int policy) { 52221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 523a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey 524c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey final int oldPolicy; 525a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey synchronized (mRulesLock) { 526c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey oldPolicy = getUidPolicy(uid); 527a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey mUidPolicy.put(uid, policy); 528c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey 52921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey // uid policy changed, recompute rules and persist policy. 53021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey updateRulesForUidLocked(uid); 53121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey writePolicyLocked(); 53221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 533d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey } 534d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 535d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey @Override 536d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey public int getUidPolicy(int uid) { 53721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 53821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 539a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey synchronized (mRulesLock) { 540a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey return mUidPolicy.get(uid, POLICY_NONE); 541a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 542d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey } 543d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 544c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey @Override 545c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey public void registerListener(INetworkPolicyListener listener) { 546c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey mListeners.register(listener); 547c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey 548c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey synchronized (mRulesLock) { 549c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey // dispatch any existing rules to new listeners 550c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey final int size = mUidRules.size(); 551c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey for (int i = 0; i < size; i++) { 552c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey final int uid = mUidRules.keyAt(i); 553c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey final int uidRules = mUidRules.valueAt(i); 554c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey if (uidRules != RULE_ALLOW_ALL) { 555c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey try { 556c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey listener.onRulesChanged(uid, uidRules); 557c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey } catch (RemoteException e) { 558c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey } 559c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey } 560c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey } 561c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey } 562c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey } 563c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey 564c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey @Override 565c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey public void unregisterListener(INetworkPolicyListener listener) { 566c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey mListeners.unregister(listener); 567c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey } 568c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey 5691b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey @Override 57021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey public void setNetworkPolicy(int networkType, String subscriberId, NetworkPolicy policy) { 57121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 57221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 57321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey synchronized (mRulesLock) { 57421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey mTemplatePolicy.put(new StrongTemplate(networkType, subscriberId), policy); 57521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 57621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey // network policy changed, recompute template rules based on active 57721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey // interfaces and persist policy. 57821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey updateIfacesLocked(); 57921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey writePolicyLocked(); 58021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 58121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 58221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 58321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey @Override 58421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey public NetworkPolicy getNetworkPolicy(int networkType, String subscriberId) { 58521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 58621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 58721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey synchronized (mRulesLock) { 58821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey return mTemplatePolicy.get(new StrongTemplate(networkType, subscriberId)); 58921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 59021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 59121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 59221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey @Override 5931b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) { 59475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey mContext.enforceCallingOrSelfPermission(DUMP, TAG); 5951b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey 5961b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey synchronized (mRulesLock) { 59721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey fout.println("Network policies:"); 59821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey for (StrongTemplate template : mTemplatePolicy.keySet()) { 59921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final NetworkPolicy policy = mTemplatePolicy.get(template); 60021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey fout.print(" "); fout.println(template.toString()); 60121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey fout.print(" "); fout.println(policy.toString()); 60221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 60321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 6041b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey fout.println("Policy status for known UIDs:"); 6051b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey 6061b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey final SparseBooleanArray knownUids = new SparseBooleanArray(); 6071b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey collectKeys(mUidPolicy, knownUids); 6081b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey collectKeys(mUidForeground, knownUids); 6091b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey collectKeys(mUidRules, knownUids); 6101b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey 6111b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey final int size = knownUids.size(); 6121b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey for (int i = 0; i < size; i++) { 6131b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey final int uid = knownUids.keyAt(i); 6141b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey fout.print(" UID="); 6151b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey fout.print(uid); 6161b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey 6171b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey fout.print(" policy="); 6181b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey final int policyIndex = mUidPolicy.indexOfKey(uid); 6191b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey if (policyIndex < 0) { 6201b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey fout.print("UNKNOWN"); 6211b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } else { 6221b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey dumpPolicy(fout, mUidPolicy.valueAt(policyIndex)); 6231b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } 6241b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey 6251b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey fout.print(" foreground="); 6261b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey final int foregroundIndex = mUidPidForeground.indexOfKey(uid); 6271b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey if (foregroundIndex < 0) { 6281b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey fout.print("UNKNOWN"); 6291b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } else { 6301b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey dumpSparseBooleanArray(fout, mUidPidForeground.valueAt(foregroundIndex)); 6311b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } 6321b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey 6331b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey fout.print(" rules="); 6341b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey final int rulesIndex = mUidRules.indexOfKey(uid); 6351b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey if (rulesIndex < 0) { 6361b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey fout.print("UNKNOWN"); 6371b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } else { 6381b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey dumpRules(fout, mUidRules.valueAt(rulesIndex)); 6391b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } 6401b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey 6411b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey fout.println(); 6421b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } 6431b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } 6441b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } 6459599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey 6469599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey @Override 6479599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey public boolean isUidForeground(int uid) { 6489599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey synchronized (mRulesLock) { 6499599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey // only really in foreground when screen is also on 6509599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey return mUidForeground.get(uid, false) && mScreenOn; 6519599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey } 652c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey } 653c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey 654d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey /** 655d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey * Foreground for PID changed; recompute foreground at UID level. If 65621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey * changed, will trigger {@link #updateRulesForUidLocked(int)}. 657d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey */ 65821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private void computeUidForegroundLocked(int uid) { 659d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey final SparseBooleanArray pidForeground = mUidPidForeground.get(uid); 660d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 661d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey // current pid is dropping foreground; examine other pids 662d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey boolean uidForeground = false; 663d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey final int size = pidForeground.size(); 664d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey for (int i = 0; i < size; i++) { 665d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey if (pidForeground.valueAt(i)) { 666d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey uidForeground = true; 667d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey break; 668d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey } 669d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey } 670d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 671d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey final boolean oldUidForeground = mUidForeground.get(uid, false); 672d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey if (oldUidForeground != uidForeground) { 673d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey // foreground changed, push updated rules 674d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey mUidForeground.put(uid, uidForeground); 67521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey updateRulesForUidLocked(uid); 676a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 677a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 678a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey 679a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey private void updateScreenOn() { 680a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey synchronized (mRulesLock) { 681a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey try { 682a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey mScreenOn = mPowerManager.isScreenOn(); 683a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } catch (RemoteException e) { 684a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 68521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey updateRulesForScreenLocked(); 686d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey } 687d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey } 688d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 689a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey /** 690a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey * Update rules that might be changed by {@link #mScreenOn} value. 691a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey */ 69221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private void updateRulesForScreenLocked() { 693a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey // only update rules for anyone with foreground activities 694a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey final int size = mUidForeground.size(); 695a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey for (int i = 0; i < size; i++) { 696a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey if (mUidForeground.valueAt(i)) { 697a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey final int uid = mUidForeground.keyAt(i); 69821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey updateRulesForUidLocked(uid); 699a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 700a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 701a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 702a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey 70321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private void updateRulesForUidLocked(int uid) { 704d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey final int uidPolicy = getUidPolicy(uid); 7059599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey final boolean uidForeground = isUidForeground(uid); 706d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 707c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey // derive active rules based on policy and active state 708c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey int uidRules = RULE_ALLOW_ALL; 709c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey if (!uidForeground && (uidPolicy & POLICY_REJECT_PAID_BACKGROUND) != 0) { 710c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey // uid in background, and policy says to block paid data 711c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey uidRules = RULE_REJECT_PAID; 712d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey } 713d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 714c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey // TODO: only dispatch when rules actually change 715c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey 716c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey // record rule locally to dispatch to new listeners 717c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey mUidRules.put(uid, uidRules); 718c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey 719c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey // dispatch changed rule to existing listeners 720c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey final int length = mListeners.beginBroadcast(); 721c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey for (int i = 0; i < length; i++) { 722c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey final INetworkPolicyListener listener = mListeners.getBroadcastItem(i); 723c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey if (listener != null) { 724c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey try { 725c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey listener.onRulesChanged(uid, uidRules); 726c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey } catch (RemoteException e) { 727c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey } 728c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey } 729d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey } 730c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey mListeners.finishBroadcast(); 731d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey } 732d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 7331b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey private static void collectKeys(SparseIntArray source, SparseBooleanArray target) { 7341b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey final int size = source.size(); 7351b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey for (int i = 0; i < size; i++) { 7361b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey target.put(source.keyAt(i), true); 7371b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } 7381b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } 7391b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey 7401b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey private static void collectKeys(SparseBooleanArray source, SparseBooleanArray target) { 7411b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey final int size = source.size(); 7421b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey for (int i = 0; i < size; i++) { 7431b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey target.put(source.keyAt(i), true); 7441b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } 7451b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } 7461b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey 7471b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey private static void dumpSparseBooleanArray(PrintWriter fout, SparseBooleanArray value) { 7481b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey fout.print("["); 7491b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey final int size = value.size(); 7501b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey for (int i = 0; i < size; i++) { 7511b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey fout.print(value.keyAt(i) + "=" + value.valueAt(i)); 7521b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey if (i < size - 1) fout.print(","); 7531b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } 7541b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey fout.print("]"); 7551b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } 75621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 75721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private static int readIntAttribute(XmlPullParser in, String name) throws IOException { 75821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final String value = in.getAttributeValue(null, name); 75921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey try { 76021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey return Integer.parseInt(value); 76121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } catch (NumberFormatException e) { 76221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey throw new ProtocolException("problem parsing " + name + "=" + value + " as int"); 76321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 76421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 76521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 76621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private static long readLongAttribute(XmlPullParser in, String name) throws IOException { 76721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final String value = in.getAttributeValue(null, name); 76821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey try { 76921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey return Long.parseLong(value); 77021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } catch (NumberFormatException e) { 77121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey throw new ProtocolException("problem parsing " + name + "=" + value + " as int"); 77221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 77321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 77421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 77521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private static void writeIntAttribute(XmlSerializer out, String name, int value) 77621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey throws IOException { 77721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey out.attribute(null, name, Integer.toString(value)); 77821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 77921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 78021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private static void writeLongAttribute(XmlSerializer out, String name, long value) 78121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey throws IOException { 78221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey out.attribute(null, name, Long.toString(value)); 78321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 78421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 78521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey /** 78621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey * Network template with strong subscriber ID, used as key when defining 78721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey * {@link NetworkPolicy}. 78821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey */ 78921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private static class StrongTemplate { 79021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey public final int networkTemplate; 79121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey public final String subscriberId; 79221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 79321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey public StrongTemplate(int networkTemplate, String subscriberId) { 79421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey this.networkTemplate = networkTemplate; 79521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey this.subscriberId = subscriberId; 79621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 79721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 79821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey @Override 79921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey public int hashCode() { 80021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey return Objects.hashCode(networkTemplate, subscriberId); 80121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 80221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 80321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey @Override 80421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey public boolean equals(Object obj) { 80521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey if (obj instanceof StrongTemplate) { 80621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final StrongTemplate template = (StrongTemplate) obj; 80721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey return template.networkTemplate == networkTemplate 80821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey && Objects.equal(template.subscriberId, subscriberId); 80921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 81021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey return false; 81121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 81221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 81321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey @Override 81421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey public String toString() { 81521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey return "TemplateIdentity: networkTemplate=" + networkTemplate + ", subscriberId=" 81621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey + subscriberId; 81721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 81821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 81921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 82021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 821d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey} 822