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 19f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkeyimport static android.Manifest.permission.ACCESS_NETWORK_STATE; 2021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport static android.Manifest.permission.CONNECTIVITY_INTERNAL; 211b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkeyimport static android.Manifest.permission.DUMP; 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; 27d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkeyimport static android.content.Intent.ACTION_USER_ADDED; 28d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkeyimport static android.content.Intent.ACTION_USER_REMOVED; 29b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkeyimport static android.content.Intent.EXTRA_UID; 30961e30458319cfd50e1892ba7dd14a1d0ebe4cc7Jeff Sharkeyimport static android.net.ConnectivityManager.CONNECTIVITY_ACTION_IMMEDIATE; 318e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkeyimport static android.net.ConnectivityManager.TYPE_ETHERNET; 321b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkeyimport static android.net.ConnectivityManager.TYPE_MOBILE; 338e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkeyimport static android.net.ConnectivityManager.TYPE_WIFI; 348e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkeyimport static android.net.ConnectivityManager.TYPE_WIMAX; 359f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkeyimport static android.net.ConnectivityManager.isNetworkTypeMobile; 369f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkeyimport static android.net.NetworkPolicy.CYCLE_NONE; 3722c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkeyimport static android.net.NetworkPolicy.LIMIT_DISABLED; 3841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkeyimport static android.net.NetworkPolicy.SNOOZE_NEVER; 39497e4437af386930dff3bd55296d128bd4520959Jeff Sharkeyimport static android.net.NetworkPolicy.WARNING_DISABLED; 4014711eb5b6a45b587222ae71c57a381beb7b1a7eJeff Sharkeyimport static android.net.NetworkPolicyManager.EXTRA_NETWORK_TEMPLATE; 41d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkeyimport static android.net.NetworkPolicyManager.POLICY_NONE; 42fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkeyimport static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND; 43c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkeyimport static android.net.NetworkPolicyManager.RULE_ALLOW_ALL; 44fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkeyimport static android.net.NetworkPolicyManager.RULE_REJECT_METERED; 45cd2ca4038a027315832c38c68be5076000bc4b53Jeff Sharkeyimport static android.net.NetworkPolicyManager.computeLastCycleBoundary; 461b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkeyimport static android.net.NetworkPolicyManager.dumpPolicy; 471b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkeyimport static android.net.NetworkPolicyManager.dumpRules; 488e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkeyimport static android.net.NetworkTemplate.MATCH_ETHERNET; 491b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkeyimport static android.net.NetworkTemplate.MATCH_MOBILE_3G_LOWER; 501b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkeyimport static android.net.NetworkTemplate.MATCH_MOBILE_4G; 518e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkeyimport static android.net.NetworkTemplate.MATCH_MOBILE_ALL; 528e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkeyimport static android.net.NetworkTemplate.MATCH_WIFI; 534e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkeyimport static android.net.NetworkTemplate.buildTemplateMobileAll; 54241dde2306202e7655fdf41d5381f2874e47e108Jeff Sharkeyimport static android.net.TrafficStats.MB_IN_BYTES; 559f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkeyimport static android.net.wifi.WifiInfo.removeDoubleQuotes; 569f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkeyimport static android.net.wifi.WifiManager.CHANGE_REASON_ADDED; 579f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkeyimport static android.net.wifi.WifiManager.CHANGE_REASON_REMOVED; 589f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkeyimport static android.net.wifi.WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION; 599f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkeyimport static android.net.wifi.WifiManager.EXTRA_CHANGE_REASON; 609f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkeyimport static android.net.wifi.WifiManager.EXTRA_NETWORK_INFO; 619f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkeyimport static android.net.wifi.WifiManager.EXTRA_WIFI_CONFIGURATION; 629f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkeyimport static android.net.wifi.WifiManager.EXTRA_WIFI_INFO; 638fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkeyimport static android.telephony.TelephonyManager.SIM_STATE_READY; 6421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport static android.text.format.DateUtils.DAY_IN_MILLIS; 65854b2b1670bda1eeb87a14b7ac3d222024f0aad6Jeff Sharkeyimport static com.android.internal.util.ArrayUtils.appendInt; 6621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport static com.android.internal.util.Preconditions.checkNotNull; 67961e30458319cfd50e1892ba7dd14a1d0ebe4cc7Jeff Sharkeyimport static com.android.server.NetworkManagementService.LIMIT_GLOBAL_ALERT; 684664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkeyimport static com.android.server.net.NetworkPolicyManagerService.XmlUtils.readBooleanAttribute; 694664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkeyimport static com.android.server.net.NetworkPolicyManagerService.XmlUtils.readIntAttribute; 704664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkeyimport static com.android.server.net.NetworkPolicyManagerService.XmlUtils.readLongAttribute; 714664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkeyimport static com.android.server.net.NetworkPolicyManagerService.XmlUtils.writeBooleanAttribute; 724664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkeyimport static com.android.server.net.NetworkPolicyManagerService.XmlUtils.writeIntAttribute; 734664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkeyimport static com.android.server.net.NetworkPolicyManagerService.XmlUtils.writeLongAttribute; 74497e4437af386930dff3bd55296d128bd4520959Jeff Sharkeyimport static com.android.server.net.NetworkStatsService.ACTION_NETWORK_STATS_UPDATED; 7521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 7621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport static org.xmlpull.v1.XmlPullParser.START_TAG; 77d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 78a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkeyimport android.app.IActivityManager; 79497e4437af386930dff3bd55296d128bd4520959Jeff Sharkeyimport android.app.INotificationManager; 80a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkeyimport android.app.IProcessObserver; 81497e4437af386930dff3bd55296d128bd4520959Jeff Sharkeyimport android.app.Notification; 82497e4437af386930dff3bd55296d128bd4520959Jeff Sharkeyimport android.app.PendingIntent; 83a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkeyimport android.content.BroadcastReceiver; 8441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkeyimport android.content.ComponentName; 85d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkeyimport android.content.Context; 86a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkeyimport android.content.Intent; 87a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkeyimport android.content.IntentFilter; 88b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkeyimport android.content.pm.ApplicationInfo; 89b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkeyimport android.content.pm.PackageManager; 908a8b581e669f6187b397f856a567a76ed8aba2c2Jeff Sharkeyimport android.content.pm.UserInfo; 91497e4437af386930dff3bd55296d128bd4520959Jeff Sharkeyimport android.content.res.Resources; 92c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkeyimport android.net.ConnectivityManager; 9321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport android.net.IConnectivityManager; 9441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkeyimport android.net.INetworkManagementEventObserver; 95c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkeyimport android.net.INetworkPolicyListener; 96d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkeyimport android.net.INetworkPolicyManager; 9775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.net.INetworkStatsService; 981b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkeyimport android.net.NetworkIdentity; 999f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkeyimport android.net.NetworkInfo; 10021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport android.net.NetworkPolicy; 101f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkeyimport android.net.NetworkQuotaInfo; 10221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport android.net.NetworkState; 1031b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkeyimport android.net.NetworkTemplate; 1049f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkeyimport android.net.wifi.WifiConfiguration; 1059f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkeyimport android.net.wifi.WifiInfo; 1069f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkeyimport android.net.wifi.WifiManager; 107f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkeyimport android.os.Binder; 10821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport android.os.Environment; 10921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport android.os.Handler; 11021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport android.os.HandlerThread; 11150fd36d7c38c40b087c8f3e3172478abe0c051d9Ashish Sharmaimport android.os.INetworkManagementService; 112a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkeyimport android.os.IPowerManager; 1134414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkeyimport android.os.Message; 114163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkeyimport android.os.MessageQueue.IdleHandler; 115c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkeyimport android.os.RemoteCallbackList; 116a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkeyimport android.os.RemoteException; 117f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackbornimport android.os.UserHandle; 118258848d2ae04f447ff1c18023fa76b139fcc0862Amith Yamasaniimport android.os.UserManager; 1193a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkeyimport android.provider.Settings; 12022c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkeyimport android.telephony.TelephonyManager; 121497e4437af386930dff3bd55296d128bd4520959Jeff Sharkeyimport android.text.format.Formatter; 12222c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkeyimport android.text.format.Time; 12339606a007a5b1309dd000234f2b8cf156c49fd0fDianne Hackbornimport android.util.AtomicFile; 124b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkeyimport android.util.Log; 12521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport android.util.NtpTrustedTime; 126a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkeyimport android.util.Slog; 127d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkeyimport android.util.SparseArray; 128d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkeyimport android.util.SparseBooleanArray; 129d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkeyimport android.util.SparseIntArray; 13021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport android.util.TrustedTime; 13121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport android.util.Xml; 132d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 133497e4437af386930dff3bd55296d128bd4520959Jeff Sharkeyimport com.android.internal.R; 13421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport com.android.internal.util.FastXmlSerializer; 1358fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkeyimport com.android.internal.util.IndentingPrintWriter; 1368e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkeyimport com.android.internal.util.Objects; 13721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport com.google.android.collect.Lists; 13821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport com.google.android.collect.Maps; 139fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkeyimport com.google.android.collect.Sets; 14021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 14121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport org.xmlpull.v1.XmlPullParser; 14221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport org.xmlpull.v1.XmlPullParserException; 14321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport org.xmlpull.v1.XmlSerializer; 14421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 14521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport java.io.File; 1461b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkeyimport java.io.FileDescriptor; 14721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport java.io.FileInputStream; 14821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport java.io.FileNotFoundException; 14921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport java.io.FileOutputStream; 15021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport java.io.IOException; 1511b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkeyimport java.io.PrintWriter; 15221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport java.net.ProtocolException; 15321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport java.util.ArrayList; 15421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport java.util.Arrays; 15521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport java.util.HashMap; 156fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkeyimport java.util.HashSet; 157b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkeyimport java.util.List; 15847eb102b40cd1324d89816a7fb0fecd14fd7a408Jeff Sharkeyimport java.util.Map; 15921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 16021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport libcore.io.IoUtils; 1611b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey 162d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey/** 1638e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey * Service that maintains low-level network policy rules, using 1648e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey * {@link NetworkStatsService} statistics to drive those rules. 165c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey * <p> 166c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey * Derives active rules by combining a given policy with other system status, 167c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey * and delivers to listeners, such as {@link ConnectivityManager}, for 168c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey * enforcement. 169d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey */ 170d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkeypublic class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { 171d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey private static final String TAG = "NetworkPolicy"; 172ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey private static final boolean LOGD = false; 17322c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey private static final boolean LOGV = false; 174d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 17541ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey private static final int VERSION_INIT = 1; 17641ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey private static final int VERSION_ADDED_SNOOZE = 2; 1774664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey private static final int VERSION_ADDED_RESTRICT_BACKGROUND = 3; 178f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey private static final int VERSION_ADDED_METERED = 4; 1790e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey private static final int VERSION_SPLIT_SNOOZE = 5; 1809bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey private static final int VERSION_ADDED_TIMEZONE = 6; 181837f9242ae2e8f5f380d0b30b8fffbc68494914fJeff Sharkey private static final int VERSION_ADDED_INFERRED = 7; 1828a8b581e669f6187b397f856a567a76ed8aba2c2Jeff Sharkey private static final int VERSION_SWITCH_APP_ID = 8; 1838fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey private static final int VERSION_ADDED_NETWORK_ID = 9; 184d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey private static final int VERSION_SWITCH_UID = 10; 185d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey private static final int VERSION_LATEST = VERSION_SWITCH_UID; 18621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 18741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey // @VisibleForTesting 18841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey public static final int TYPE_WARNING = 0x1; 18941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey public static final int TYPE_LIMIT = 0x2; 19041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey public static final int TYPE_LIMIT_SNOOZED = 0x3; 191497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey 19221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private static final String TAG_POLICY_LIST = "policy-list"; 19321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private static final String TAG_NETWORK_POLICY = "network-policy"; 19421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private static final String TAG_UID_POLICY = "uid-policy"; 1958a8b581e669f6187b397f856a567a76ed8aba2c2Jeff Sharkey private static final String TAG_APP_POLICY = "app-policy"; 19621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 19721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private static final String ATTR_VERSION = "version"; 1984664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey private static final String ATTR_RESTRICT_BACKGROUND = "restrictBackground"; 19921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private static final String ATTR_NETWORK_TEMPLATE = "networkTemplate"; 20021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private static final String ATTR_SUBSCRIBER_ID = "subscriberId"; 2018fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey private static final String ATTR_NETWORK_ID = "networkId"; 20221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private static final String ATTR_CYCLE_DAY = "cycleDay"; 2039bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey private static final String ATTR_CYCLE_TIMEZONE = "cycleTimezone"; 20421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private static final String ATTR_WARNING_BYTES = "warningBytes"; 20521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private static final String ATTR_LIMIT_BYTES = "limitBytes"; 20641ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey private static final String ATTR_LAST_SNOOZE = "lastSnooze"; 2070e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey private static final String ATTR_LAST_WARNING_SNOOZE = "lastWarningSnooze"; 2080e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey private static final String ATTR_LAST_LIMIT_SNOOZE = "lastLimitSnooze"; 209f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey private static final String ATTR_METERED = "metered"; 210837f9242ae2e8f5f380d0b30b8fffbc68494914fJeff Sharkey private static final String ATTR_INFERRED = "inferred"; 21121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private static final String ATTR_UID = "uid"; 2128a8b581e669f6187b397f856a567a76ed8aba2c2Jeff Sharkey private static final String ATTR_APP_ID = "appId"; 21321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private static final String ATTR_POLICY = "policy"; 21421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 2153a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey private static final String TAG_ALLOW_BACKGROUND = TAG + ":allowBackground"; 2163a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey 2173a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey // @VisibleForTesting 2183a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey public static final String ACTION_ALLOW_BACKGROUND = 2190e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey "com.android.server.net.action.ALLOW_BACKGROUND"; 2200e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey public static final String ACTION_SNOOZE_WARNING = 2210e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey "com.android.server.net.action.SNOOZE_WARNING"; 2223a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey 22321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private static final long TIME_CACHE_MAX_AGE = DAY_IN_MILLIS; 22421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 2256f7af03cf13f76f48e63937e13e4a1c508d100d6Jeff Sharkey private static final int MSG_RULES_CHANGED = 1; 2266f7af03cf13f76f48e63937e13e4a1c508d100d6Jeff Sharkey private static final int MSG_METERED_IFACES_CHANGED = 2; 2276f7af03cf13f76f48e63937e13e4a1c508d100d6Jeff Sharkey private static final int MSG_FOREGROUND_ACTIVITIES_CHANGED = 3; 2286f7af03cf13f76f48e63937e13e4a1c508d100d6Jeff Sharkey private static final int MSG_PROCESS_DIED = 4; 2297e25b0ea8891ffc0ac472d61f21610a9ac4e270aJeff Sharkey private static final int MSG_LIMIT_REACHED = 5; 2301f8ea2dcd1ed3cde4b84fbb27b5a55b3fea7ff2aJeff Sharkey private static final int MSG_RESTRICT_BACKGROUND_CHANGED = 6; 231e19f39b79c831aea4d51a3309025acdf69d1e609Jeff Sharkey private static final int MSG_ADVISE_PERSIST_THRESHOLD = 7; 2320abe556d28f5f5d395559cc6567b05939d1b2640Jeff Sharkey private static final int MSG_SCREEN_ON_CHANGED = 8; 2334414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey 23475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey private final Context mContext; 23575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey private final IActivityManager mActivityManager; 23675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey private final IPowerManager mPowerManager; 23775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey private final INetworkStatsService mNetworkStats; 23841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey private final INetworkManagementService mNetworkManager; 23921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private final TrustedTime mTime; 24021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 24121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private IConnectivityManager mConnManager; 242497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey private INotificationManager mNotifManager; 243a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey 24475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey private final Object mRulesLock = new Object(); 245a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey 2463a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey private volatile boolean mScreenOn; 2473a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey private volatile boolean mRestrictBackground; 248d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 2498e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey private final boolean mSuppressDefaultPolicy; 2508e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey 25141ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey /** Defined network policies. */ 25241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey private HashMap<NetworkTemplate, NetworkPolicy> mNetworkPolicy = Maps.newHashMap(); 25341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey /** Currently active network rules for ifaces. */ 25402e21d6a5b5117d494777a36783909854854f751Jeff Sharkey private HashMap<NetworkPolicy, String[]> mNetworkRules = Maps.newHashMap(); 25522c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey 256d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey /** Defined UID policies. */ 257d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey private SparseIntArray mUidPolicy = new SparseIntArray(); 25841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey /** Currently derived rules for each UID. */ 259c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey private SparseIntArray mUidRules = new SparseIntArray(); 260d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 261fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey /** Set of ifaces that are metered. */ 262fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey private HashSet<String> mMeteredIfaces = Sets.newHashSet(); 26341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey /** Set of over-limit templates that have been notified. */ 26441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey private HashSet<NetworkTemplate> mOverLimitNotified = Sets.newHashSet(); 265fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey 2668e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey /** Set of currently active {@link Notification} tags. */ 2678e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey private HashSet<String> mActiveNotifs = Sets.newHashSet(); 2688e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey 269d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey /** Foreground at both UID and PID granularity. */ 270a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey private SparseBooleanArray mUidForeground = new SparseBooleanArray(); 271a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey private SparseArray<SparseBooleanArray> mUidPidForeground = new SparseArray< 272a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey SparseBooleanArray>(); 273d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 274c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey private final RemoteCallbackList<INetworkPolicyListener> mListeners = new RemoteCallbackList< 275c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey INetworkPolicyListener>(); 276c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey 27721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private final HandlerThread mHandlerThread; 27821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private final Handler mHandler; 27921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 28021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private final AtomicFile mPolicyFile; 281d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 282c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey // TODO: keep whitelist of system-critical services that should never have 283c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey // rules enforced, such as system, phone, and radio UIDs. 284c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey 28541ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey // TODO: migrate notifications to SystemUI 28641ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey 28775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey public NetworkPolicyManagerService(Context context, IActivityManager activityManager, 28850fd36d7c38c40b087c8f3e3172478abe0c051d9Ashish Sharma IPowerManager powerManager, INetworkStatsService networkStats, 28950fd36d7c38c40b087c8f3e3172478abe0c051d9Ashish Sharma INetworkManagementService networkManagement) { 290b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey this(context, activityManager, powerManager, networkStats, networkManagement, 2918e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey NtpTrustedTime.getInstance(context), getSystemDir(), false); 29221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 29321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 29421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private static File getSystemDir() { 29521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey return new File(Environment.getDataDirectory(), "system"); 29621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 29721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 29821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey public NetworkPolicyManagerService(Context context, IActivityManager activityManager, 29950fd36d7c38c40b087c8f3e3172478abe0c051d9Ashish Sharma IPowerManager powerManager, INetworkStatsService networkStats, 3008e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey INetworkManagementService networkManagement, TrustedTime time, File systemDir, 3018e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey boolean suppressDefaultPolicy) { 302a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey mContext = checkNotNull(context, "missing context"); 303a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey mActivityManager = checkNotNull(activityManager, "missing activityManager"); 304a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey mPowerManager = checkNotNull(powerManager, "missing powerManager"); 30575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey mNetworkStats = checkNotNull(networkStats, "missing networkStats"); 30641ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey mNetworkManager = checkNotNull(networkManagement, "missing networkManagement"); 30721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey mTime = checkNotNull(time, "missing TrustedTime"); 30821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 30921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey mHandlerThread = new HandlerThread(TAG); 31021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey mHandlerThread.start(); 3114414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey mHandler = new Handler(mHandlerThread.getLooper(), mHandlerCallback); 31221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 3138e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey mSuppressDefaultPolicy = suppressDefaultPolicy; 3148e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey 31521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey mPolicyFile = new AtomicFile(new File(systemDir, "netpolicy.xml")); 31621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 31721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 31821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey public void bindConnectivityManager(IConnectivityManager connManager) { 31921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey mConnManager = checkNotNull(connManager, "missing IConnectivityManager"); 320a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 321d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 322497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey public void bindNotificationManager(INotificationManager notifManager) { 323497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey mNotifManager = checkNotNull(notifManager, "missing INotificationManager"); 324497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey } 325497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey 326a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey public void systemReady() { 3278c1dc72b1402d55dae388a294476565b2473a87aJeff Sharkey if (!isBandwidthControlEnabled()) { 3288c1dc72b1402d55dae388a294476565b2473a87aJeff Sharkey Slog.w(TAG, "bandwidth controls disabled, unable to enforce policy"); 3298c1dc72b1402d55dae388a294476565b2473a87aJeff Sharkey return; 3308c1dc72b1402d55dae388a294476565b2473a87aJeff Sharkey } 3318c1dc72b1402d55dae388a294476565b2473a87aJeff Sharkey 33221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey synchronized (mRulesLock) { 33321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey // read policy from disk 33421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey readPolicyLocked(); 3354664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey 3364664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey if (mRestrictBackground) { 3374664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey updateRulesForRestrictBackgroundLocked(); 3383a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey updateNotificationsLocked(); 3394664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey } 34021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 341d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 342a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey updateScreenOn(); 343d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 344a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey try { 345a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey mActivityManager.registerProcessObserver(mProcessObserver); 34641ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey mNetworkManager.registerObserver(mAlertObserver); 34741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey } catch (RemoteException e) { 348b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey // ignored; both services live in system_server 34941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey } 35041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey 351a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey // TODO: traverse existing processes to know foreground state, or have 352a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey // activitymanager dispatch current state when new observer attached. 353d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 354a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey final IntentFilter screenFilter = new IntentFilter(); 355a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey screenFilter.addAction(Intent.ACTION_SCREEN_ON); 356a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey screenFilter.addAction(Intent.ACTION_SCREEN_OFF); 3570abe556d28f5f5d395559cc6567b05939d1b2640Jeff Sharkey mContext.registerReceiver(mScreenReceiver, screenFilter); 358d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 35921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey // watch for network interfaces to be claimed 360961e30458319cfd50e1892ba7dd14a1d0ebe4cc7Jeff Sharkey final IntentFilter connFilter = new IntentFilter(CONNECTIVITY_ACTION_IMMEDIATE); 361b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey mContext.registerReceiver(mConnReceiver, connFilter, CONNECTIVITY_INTERNAL, mHandler); 362b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey 363d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey // listen for package changes to update policy 36402e21d6a5b5117d494777a36783909854854f751Jeff Sharkey final IntentFilter packageFilter = new IntentFilter(); 36502e21d6a5b5117d494777a36783909854854f751Jeff Sharkey packageFilter.addAction(ACTION_PACKAGE_ADDED); 366d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey packageFilter.addDataScheme("package"); 36702e21d6a5b5117d494777a36783909854854f751Jeff Sharkey mContext.registerReceiver(mPackageReceiver, packageFilter, null, mHandler); 36821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 369d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey // listen for UID changes to update policy 370d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey mContext.registerReceiver( 371d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey mUidRemovedReceiver, new IntentFilter(ACTION_UID_REMOVED), null, mHandler); 372d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey 373d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey // listen for user changes to update policy 374d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey final IntentFilter userFilter = new IntentFilter(); 375d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey userFilter.addAction(ACTION_USER_ADDED); 376d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey userFilter.addAction(ACTION_USER_REMOVED); 377d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey mContext.registerReceiver(mUserReceiver, userFilter, null, mHandler); 378d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey 379b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey // listen for stats update events 380497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey final IntentFilter statsFilter = new IntentFilter(ACTION_NETWORK_STATS_UPDATED); 381497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey mContext.registerReceiver( 382497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey mStatsReceiver, statsFilter, READ_NETWORK_USAGE_HISTORY, mHandler); 383497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey 3843a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey // listen for restrict background changes from notifications 3853a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey final IntentFilter allowFilter = new IntentFilter(ACTION_ALLOW_BACKGROUND); 3863a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey mContext.registerReceiver(mAllowReceiver, allowFilter, MANAGE_NETWORK_POLICY, mHandler); 3873a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey 3880e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey // listen for snooze warning from notifications 3890e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey final IntentFilter snoozeWarningFilter = new IntentFilter(ACTION_SNOOZE_WARNING); 3900e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey mContext.registerReceiver(mSnoozeWarningReceiver, snoozeWarningFilter, 3910e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey MANAGE_NETWORK_POLICY, mHandler); 3920e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey 3939f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey // listen for configured wifi networks to be removed 3949f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey final IntentFilter wifiConfigFilter = new IntentFilter(CONFIGURED_NETWORKS_CHANGED_ACTION); 3959f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey mContext.registerReceiver( 3969f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey mWifiConfigReceiver, wifiConfigFilter, CONNECTIVITY_INTERNAL, mHandler); 3979f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey 3989f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey // listen for wifi state changes to catch metered hint 3999f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey final IntentFilter wifiStateFilter = new IntentFilter( 4009f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey WifiManager.NETWORK_STATE_CHANGED_ACTION); 4019f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey mContext.registerReceiver( 4029f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey mWifiStateReceiver, wifiStateFilter, CONNECTIVITY_INTERNAL, mHandler); 4039f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey 404a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 405d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 406a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey private IProcessObserver mProcessObserver = new IProcessObserver.Stub() { 407a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey @Override 408a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey public void onForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities) { 4096f7af03cf13f76f48e63937e13e4a1c508d100d6Jeff Sharkey mHandler.obtainMessage(MSG_FOREGROUND_ACTIVITIES_CHANGED, 4106f7af03cf13f76f48e63937e13e4a1c508d100d6Jeff Sharkey pid, uid, foregroundActivities).sendToTarget(); 411d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey } 412d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 413a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey @Override 414a93c2c117d502ee57dd27705a0b5efca4bf65011Dianne Hackborn public void onImportanceChanged(int pid, int uid, int importance) { 415a93c2c117d502ee57dd27705a0b5efca4bf65011Dianne Hackborn } 416a93c2c117d502ee57dd27705a0b5efca4bf65011Dianne Hackborn 417a93c2c117d502ee57dd27705a0b5efca4bf65011Dianne Hackborn @Override 418a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey public void onProcessDied(int pid, int uid) { 4196f7af03cf13f76f48e63937e13e4a1c508d100d6Jeff Sharkey mHandler.obtainMessage(MSG_PROCESS_DIED, pid, uid).sendToTarget(); 420a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 421a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey }; 422a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey 423a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey private BroadcastReceiver mScreenReceiver = new BroadcastReceiver() { 424a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey @Override 425a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey public void onReceive(Context context, Intent intent) { 426a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey synchronized (mRulesLock) { 427a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey // screen-related broadcasts are protected by system, no need 428a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey // for permissions check. 4290abe556d28f5f5d395559cc6567b05939d1b2640Jeff Sharkey mHandler.obtainMessage(MSG_SCREEN_ON_CHANGED).sendToTarget(); 430a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 431a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 432a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey }; 433d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 43402e21d6a5b5117d494777a36783909854854f751Jeff Sharkey private BroadcastReceiver mPackageReceiver = new BroadcastReceiver() { 435b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey @Override 436b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey public void onReceive(Context context, Intent intent) { 437d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey // on background handler thread, and PACKAGE_ADDED is protected 43802e21d6a5b5117d494777a36783909854854f751Jeff Sharkey 43902e21d6a5b5117d494777a36783909854854f751Jeff Sharkey final String action = intent.getAction(); 440d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey final int uid = intent.getIntExtra(EXTRA_UID, -1); 441d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey if (uid == -1) return; 442d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey 443d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey if (ACTION_PACKAGE_ADDED.equals(action)) { 444d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey // update rules for UID, since it might be subject to 445d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey // global background data policy 446d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey if (LOGV) Slog.v(TAG, "ACTION_PACKAGE_ADDED for uid=" + uid); 447d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey synchronized (mRulesLock) { 448d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey updateRulesForUidLocked(uid); 449d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey } 450d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey } 451d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey } 452d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey }; 453d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey 454d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey private BroadcastReceiver mUidRemovedReceiver = new BroadcastReceiver() { 455d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey @Override 456d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey public void onReceive(Context context, Intent intent) { 457d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey // on background handler thread, and UID_REMOVED is protected 458d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey 459d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey final int uid = intent.getIntExtra(EXTRA_UID, -1); 460d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey if (uid == -1) return; 461d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey 462d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey // remove any policy and update rules to clean up 463d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey if (LOGV) Slog.v(TAG, "ACTION_UID_REMOVED for uid=" + uid); 464b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey synchronized (mRulesLock) { 465d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey mUidPolicy.delete(uid); 466d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey updateRulesForUidLocked(uid); 467d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey writePolicyLocked(); 468d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey } 469d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey } 470d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey }; 4718a8b581e669f6187b397f856a567a76ed8aba2c2Jeff Sharkey 472d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey private BroadcastReceiver mUserReceiver = new BroadcastReceiver() { 473d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey @Override 474d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey public void onReceive(Context context, Intent intent) { 475d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey // on background handler thread, and USER_ADDED and USER_REMOVED 476d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey // broadcasts are protected 47702e21d6a5b5117d494777a36783909854854f751Jeff Sharkey 478d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey final String action = intent.getAction(); 479d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); 480d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey if (userId == -1) return; 4818a8b581e669f6187b397f856a567a76ed8aba2c2Jeff Sharkey 482d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey // Remove any policies for given user; both cleaning up after a 483d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey // USER_REMOVED, and one last sanity check during USER_ADDED 484d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey removePoliciesForUserLocked(userId); 4858a8b581e669f6187b397f856a567a76ed8aba2c2Jeff Sharkey 486d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey // Update global restrict for new user 487d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey synchronized (mRulesLock) { 488d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey updateRulesForRestrictBackgroundLocked(); 489b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey } 490b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey } 491b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey }; 492b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey 49321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey /** 494497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey * Receiver that watches for {@link INetworkStatsService} updates, which we 495497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey * use to check against {@link NetworkPolicy#warningBytes}. 496497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey */ 497497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey private BroadcastReceiver mStatsReceiver = new BroadcastReceiver() { 498497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey @Override 499497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey public void onReceive(Context context, Intent intent) { 500497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey // on background handler thread, and verified 501497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey // READ_NETWORK_USAGE_HISTORY permission above. 502497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey 503684c54a2eb860062f1960f4eba6bc71aa1cfa71dJeff Sharkey maybeRefreshTrustedTime(); 504497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey synchronized (mRulesLock) { 5058e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey updateNetworkEnabledLocked(); 506497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey updateNotificationsLocked(); 507497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey } 508497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey } 509497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey }; 510497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey 511497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey /** 5123a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey * Receiver that watches for {@link Notification} control of 5133a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey * {@link #mRestrictBackground}. 5143a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey */ 5153a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey private BroadcastReceiver mAllowReceiver = new BroadcastReceiver() { 5163a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey @Override 5173a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey public void onReceive(Context context, Intent intent) { 5183a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey // on background handler thread, and verified MANAGE_NETWORK_POLICY 5193a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey // permission above. 5203a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey 5213a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey setRestrictBackground(false); 5223a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey } 5233a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey }; 5243a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey 5253a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey /** 5260e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey * Receiver that watches for {@link Notification} control of 5270e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey * {@link NetworkPolicy#lastWarningSnooze}. 5280e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey */ 5290e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey private BroadcastReceiver mSnoozeWarningReceiver = new BroadcastReceiver() { 5300e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey @Override 5310e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey public void onReceive(Context context, Intent intent) { 5320e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey // on background handler thread, and verified MANAGE_NETWORK_POLICY 5330e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey // permission above. 5340e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey 5350e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey final NetworkTemplate template = intent.getParcelableExtra(EXTRA_NETWORK_TEMPLATE); 5360e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey performSnooze(template, TYPE_WARNING); 5370e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey } 5380e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey }; 5390e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey 5400e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey /** 5419f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey * Receiver that watches for {@link WifiConfiguration} to be changed. 5429f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey */ 5439f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey private BroadcastReceiver mWifiConfigReceiver = new BroadcastReceiver() { 5449f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey @Override 5459f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey public void onReceive(Context context, Intent intent) { 5469f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey // on background handler thread, and verified CONNECTIVITY_INTERNAL 5479f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey // permission above. 5489f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey 5499f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey final int reason = intent.getIntExtra(EXTRA_CHANGE_REASON, CHANGE_REASON_ADDED); 5509f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey if (reason == CHANGE_REASON_REMOVED) { 5519f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey final WifiConfiguration config = intent.getParcelableExtra( 5529f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey EXTRA_WIFI_CONFIGURATION); 55300a10a1494954d124e1b11bc1ba3128e47b8ffbdIrfan Sheriff if (config.SSID != null) { 55400a10a1494954d124e1b11bc1ba3128e47b8ffbdIrfan Sheriff final NetworkTemplate template = NetworkTemplate.buildTemplateWifi( 55500a10a1494954d124e1b11bc1ba3128e47b8ffbdIrfan Sheriff removeDoubleQuotes(config.SSID)); 55600a10a1494954d124e1b11bc1ba3128e47b8ffbdIrfan Sheriff synchronized (mRulesLock) { 55700a10a1494954d124e1b11bc1ba3128e47b8ffbdIrfan Sheriff if (mNetworkPolicy.containsKey(template)) { 55800a10a1494954d124e1b11bc1ba3128e47b8ffbdIrfan Sheriff mNetworkPolicy.remove(template); 55900a10a1494954d124e1b11bc1ba3128e47b8ffbdIrfan Sheriff writePolicyLocked(); 56000a10a1494954d124e1b11bc1ba3128e47b8ffbdIrfan Sheriff } 5619f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey } 5629f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey } 5639f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey } 5649f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey } 5659f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey }; 5669f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey 5679f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey /** 5689f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey * Receiver that watches {@link WifiInfo} state changes to infer metered 5699f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey * state. Ignores hints when policy is user-defined. 5709f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey */ 5719f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey private BroadcastReceiver mWifiStateReceiver = new BroadcastReceiver() { 5729f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey @Override 5739f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey public void onReceive(Context context, Intent intent) { 5749f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey // on background handler thread, and verified CONNECTIVITY_INTERNAL 5759f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey // permission above. 5769f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey 5779f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey // ignore when not connected 5789f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey final NetworkInfo netInfo = intent.getParcelableExtra(EXTRA_NETWORK_INFO); 5799f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey if (!netInfo.isConnected()) return; 5809f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey 5819f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey final WifiInfo info = intent.getParcelableExtra(EXTRA_WIFI_INFO); 5829f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey final boolean meteredHint = info.getMeteredHint(); 5839f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey 5849f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey final NetworkTemplate template = NetworkTemplate.buildTemplateWifi( 5859f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey removeDoubleQuotes(info.getSSID())); 5869f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey synchronized (mRulesLock) { 5879f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey NetworkPolicy policy = mNetworkPolicy.get(template); 5889f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey if (policy == null && meteredHint) { 5899f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey // policy doesn't exist, and AP is hinting that it's 5909f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey // metered: create an inferred policy. 5919f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey policy = new NetworkPolicy(template, CYCLE_NONE, Time.TIMEZONE_UTC, 5929f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey WARNING_DISABLED, LIMIT_DISABLED, SNOOZE_NEVER, SNOOZE_NEVER, 5939f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey meteredHint, true); 5949f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey addNetworkPolicyLocked(policy); 5959f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey 5969f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey } else if (policy != null && policy.inferred) { 5979f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey // policy exists, and was inferred: update its current 5989f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey // metered state. 5999f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey policy.metered = meteredHint; 6009f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey 6019f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey // since this is inferred for each wifi session, just update 6029f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey // rules without persisting. 6039f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey updateNetworkRulesLocked(); 6049f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey } 6059f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey } 6069f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey } 6079f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey }; 6089f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey 6099f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey /** 61041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey * Observer that watches for {@link INetworkManagementService} alerts. 61141ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey */ 612216c181e76ee11a47a0b2a180f9af96740ab38adJeff Sharkey private INetworkManagementEventObserver mAlertObserver = new BaseNetworkObserver() { 61341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey @Override 61441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey public void limitReached(String limitName, String iface) { 61541ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey // only someone like NMS should be calling us 61641ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 61741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey 6187e25b0ea8891ffc0ac472d61f21610a9ac4e270aJeff Sharkey if (!LIMIT_GLOBAL_ALERT.equals(limitName)) { 6197e25b0ea8891ffc0ac472d61f21610a9ac4e270aJeff Sharkey mHandler.obtainMessage(MSG_LIMIT_REACHED, iface).sendToTarget(); 62041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey } 62141ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey } 62241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey }; 62341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey 62441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey /** 625497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey * Check {@link NetworkPolicy} against current {@link INetworkStatsService} 626497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey * to show visible notifications as needed. 627497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey */ 628497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey private void updateNotificationsLocked() { 629497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey if (LOGV) Slog.v(TAG, "updateNotificationsLocked()"); 630497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey 6318e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey // keep track of previously active notifications 6328e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey final HashSet<String> beforeNotifs = Sets.newHashSet(); 6338e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey beforeNotifs.addAll(mActiveNotifs); 6348e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey mActiveNotifs.clear(); 635497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey 636497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey // TODO: when switching to kernel notifications, compute next future 637497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey // cycle boundary to recompute notifications. 638497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey 63902e21d6a5b5117d494777a36783909854854f751Jeff Sharkey // examine stats for each active policy 640684c54a2eb860062f1960f4eba6bc71aa1cfa71dJeff Sharkey final long currentTime = currentTimeMillis(); 6418e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey for (NetworkPolicy policy : mNetworkPolicy.values()) { 6428e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey // ignore policies that aren't relevant to user 6438e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey if (!isTemplateRelevant(policy.template)) continue; 6448fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey if (!policy.hasCycle()) continue; 6458e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey 646497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey final long start = computeLastCycleBoundary(currentTime, policy); 647497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey final long end = currentTime; 6488e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey final long totalBytes = getTotalBytes(policy.template, start, end); 649497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey 65050e7e51d68e3b01c3362fe9ab7b3448132e48b43Jeff Sharkey if (policy.isOverLimit(totalBytes)) { 6510e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey if (policy.lastLimitSnooze >= start) { 65241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey enqueueNotification(policy, TYPE_LIMIT_SNOOZED, totalBytes); 65341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey } else { 65441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey enqueueNotification(policy, TYPE_LIMIT, totalBytes); 65541ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey notifyOverLimitLocked(policy.template); 65641ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey } 65741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey 658497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey } else { 65941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey notifyUnderLimitLocked(policy.template); 660497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey 6610e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey if (policy.isOverWarning(totalBytes) && policy.lastWarningSnooze < start) { 66241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey enqueueNotification(policy, TYPE_WARNING, totalBytes); 663497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey } 664497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey } 66502e21d6a5b5117d494777a36783909854854f751Jeff Sharkey } 66602e21d6a5b5117d494777a36783909854854f751Jeff Sharkey 6673a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey // ongoing notification when restricting background data 6683a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey if (mRestrictBackground) { 6693a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey enqueueRestrictedNotification(TAG_ALLOW_BACKGROUND); 6703a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey } 6718e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey 6728e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey // cancel stale notifications that we didn't renew above 6738e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey for (String tag : beforeNotifs) { 6748e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey if (!mActiveNotifs.contains(tag)) { 6758e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey cancelNotification(tag); 6768e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey } 6778e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey } 6788e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey } 6798e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey 6808e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey /** 6818e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey * Test if given {@link NetworkTemplate} is relevant to user based on 6828fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey * current device state, such as when 6838fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey * {@link TelephonyManager#getSubscriberId()} matches. This is regardless of 6848fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey * data connection status. 6858e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey */ 6868e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey private boolean isTemplateRelevant(NetworkTemplate template) { 6878fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey final TelephonyManager tele = TelephonyManager.from(mContext); 6888fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey 6898e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey switch (template.getMatchRule()) { 6908e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey case MATCH_MOBILE_3G_LOWER: 6918e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey case MATCH_MOBILE_4G: 6928e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey case MATCH_MOBILE_ALL: 6938fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey // mobile templates are relevant when SIM is ready and 6948fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey // subscriberId matches. 6958fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey if (tele.getSimState() == SIM_STATE_READY) { 6968fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey return Objects.equal(tele.getSubscriberId(), template.getSubscriberId()); 6978fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey } else { 6983a66cf3e86f351f0957188a4b874a3e65edfa40fJeff Sharkey return false; 6993a66cf3e86f351f0957188a4b874a3e65edfa40fJeff Sharkey } 7008e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey } 7018e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey return true; 702497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey } 703497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey 704497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey /** 70541ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey * Notify that given {@link NetworkTemplate} is over 70641ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey * {@link NetworkPolicy#limitBytes}, potentially showing dialog to user. 70741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey */ 70841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey private void notifyOverLimitLocked(NetworkTemplate template) { 70941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey if (!mOverLimitNotified.contains(template)) { 71041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey mContext.startActivity(buildNetworkOverLimitIntent(template)); 71141ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey mOverLimitNotified.add(template); 71241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey } 71341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey } 71441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey 71541ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey private void notifyUnderLimitLocked(NetworkTemplate template) { 71641ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey mOverLimitNotified.remove(template); 71741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey } 71841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey 71941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey /** 720497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey * Build unique tag that identifies an active {@link NetworkPolicy} 721497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey * notification of a specific type, like {@link #TYPE_LIMIT}. 722497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey */ 723497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey private String buildNotificationTag(NetworkPolicy policy, int type) { 7241b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey return TAG + ":" + policy.template.hashCode() + ":" + type; 725497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey } 726497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey 727497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey /** 728497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey * Show notification for combined {@link NetworkPolicy} and specific type, 729497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey * like {@link #TYPE_LIMIT}. Okay to call multiple times. 730497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey */ 73141ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey private void enqueueNotification(NetworkPolicy policy, int type, long totalBytes) { 732497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey final String tag = buildNotificationTag(policy, type); 733497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey final Notification.Builder builder = new Notification.Builder(mContext); 734497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey builder.setOnlyAlertOnce(true); 7350e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey builder.setWhen(0L); 736497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey 737497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey final Resources res = mContext.getResources(); 738497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey switch (type) { 739497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey case TYPE_WARNING: { 74041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey final CharSequence title = res.getText(R.string.data_usage_warning_title); 7418ca953da93eb8679574abba535f75f72d50016f2Jeff Sharkey final CharSequence body = res.getString(R.string.data_usage_warning_body); 742497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey 74350e7e51d68e3b01c3362fe9ab7b3448132e48b43Jeff Sharkey builder.setSmallIcon(R.drawable.stat_notify_error); 744497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey builder.setTicker(title); 745497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey builder.setContentTitle(title); 746497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey builder.setContentText(body); 74714711eb5b6a45b587222ae71c57a381beb7b1a7eJeff Sharkey 7480e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey final Intent snoozeIntent = buildSnoozeWarningIntent(policy.template); 7490e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey builder.setDeleteIntent(PendingIntent.getBroadcast( 7500e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey mContext, 0, snoozeIntent, PendingIntent.FLAG_UPDATE_CURRENT)); 7510e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey 7520e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey final Intent viewIntent = buildViewDataUsageIntent(policy.template); 75314711eb5b6a45b587222ae71c57a381beb7b1a7eJeff Sharkey builder.setContentIntent(PendingIntent.getActivity( 7540e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey mContext, 0, viewIntent, PendingIntent.FLAG_UPDATE_CURRENT)); 7550e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey 756497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey break; 757497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey } 758497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey case TYPE_LIMIT: { 75941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey final CharSequence body = res.getText(R.string.data_usage_limit_body); 76041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey 76141ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey final CharSequence title; 7621b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey switch (policy.template.getMatchRule()) { 7631b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey case MATCH_MOBILE_3G_LOWER: 76441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey title = res.getText(R.string.data_usage_3g_limit_title); 765497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey break; 7661b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey case MATCH_MOBILE_4G: 76741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey title = res.getText(R.string.data_usage_4g_limit_title); 768497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey break; 7698e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey case MATCH_MOBILE_ALL: 77041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey title = res.getText(R.string.data_usage_mobile_limit_title); 771497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey break; 7728e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey case MATCH_WIFI: 7738e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey title = res.getText(R.string.data_usage_wifi_limit_title); 7748e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey break; 7758e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey default: 7768e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey title = null; 7778e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey break; 778497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey } 779497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey 7800e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey builder.setOngoing(true); 78150e7e51d68e3b01c3362fe9ab7b3448132e48b43Jeff Sharkey builder.setSmallIcon(R.drawable.stat_notify_disabled); 782497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey builder.setTicker(title); 783497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey builder.setContentTitle(title); 784497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey builder.setContentText(body); 78514711eb5b6a45b587222ae71c57a381beb7b1a7eJeff Sharkey 78641ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey final Intent intent = buildNetworkOverLimitIntent(policy.template); 78741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey builder.setContentIntent(PendingIntent.getActivity( 78841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)); 78941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey break; 79041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey } 79141ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey case TYPE_LIMIT_SNOOZED: { 79241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey final long overBytes = totalBytes - policy.limitBytes; 79341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey final CharSequence body = res.getString(R.string.data_usage_limit_snoozed_body, 79441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey Formatter.formatFileSize(mContext, overBytes)); 79541ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey 79641ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey final CharSequence title; 79741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey switch (policy.template.getMatchRule()) { 79841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey case MATCH_MOBILE_3G_LOWER: 79941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey title = res.getText(R.string.data_usage_3g_limit_snoozed_title); 80041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey break; 80141ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey case MATCH_MOBILE_4G: 80241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey title = res.getText(R.string.data_usage_4g_limit_snoozed_title); 80341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey break; 8048e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey case MATCH_MOBILE_ALL: 80541ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey title = res.getText(R.string.data_usage_mobile_limit_snoozed_title); 80641ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey break; 8078e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey case MATCH_WIFI: 8088e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey title = res.getText(R.string.data_usage_wifi_limit_snoozed_title); 8098e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey break; 8108e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey default: 8118e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey title = null; 8128e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey break; 81341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey } 81441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey 8150e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey builder.setOngoing(true); 81650e7e51d68e3b01c3362fe9ab7b3448132e48b43Jeff Sharkey builder.setSmallIcon(R.drawable.stat_notify_error); 81741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey builder.setTicker(title); 81841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey builder.setContentTitle(title); 81941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey builder.setContentText(body); 82041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey 82141ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey final Intent intent = buildViewDataUsageIntent(policy.template); 82214711eb5b6a45b587222ae71c57a381beb7b1a7eJeff Sharkey builder.setContentIntent(PendingIntent.getActivity( 82314711eb5b6a45b587222ae71c57a381beb7b1a7eJeff Sharkey mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)); 824497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey break; 825497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey } 826497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey } 827497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey 828497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey // TODO: move to NotificationManager once we can mock it 8294120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn // XXX what to do about multi-user? 830497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey try { 831497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey final String packageName = mContext.getPackageName(); 832497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey final int[] idReceived = new int[1]; 833497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey mNotifManager.enqueueNotificationWithTag( 8344120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn packageName, tag, 0x0, builder.getNotification(), idReceived, 8354120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn UserHandle.USER_OWNER); 8368e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey mActiveNotifs.add(tag); 837497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey } catch (RemoteException e) { 838b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey // ignored; service lives in system_server 839497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey } 840497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey } 841497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey 842497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey /** 8433a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey * Show ongoing notification to reflect that {@link #mRestrictBackground} 8443a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey * has been enabled. 8453a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey */ 8463a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey private void enqueueRestrictedNotification(String tag) { 8473a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey final Resources res = mContext.getResources(); 8483a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey final Notification.Builder builder = new Notification.Builder(mContext); 8493a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey 8503a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey final CharSequence title = res.getText(R.string.data_usage_restricted_title); 8513a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey final CharSequence body = res.getString(R.string.data_usage_restricted_body); 8523a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey 8533a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey builder.setOnlyAlertOnce(true); 8543a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey builder.setOngoing(true); 85550e7e51d68e3b01c3362fe9ab7b3448132e48b43Jeff Sharkey builder.setSmallIcon(R.drawable.stat_notify_error); 8563a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey builder.setTicker(title); 8573a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey builder.setContentTitle(title); 8583a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey builder.setContentText(body); 8593a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey 8603a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey final Intent intent = buildAllowBackgroundDataIntent(); 8613a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey builder.setContentIntent( 8623a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey PendingIntent.getBroadcast(mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)); 8633a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey 8643a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey // TODO: move to NotificationManager once we can mock it 8654120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn // XXX what to do about multi-user? 8663a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey try { 8673a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey final String packageName = mContext.getPackageName(); 8683a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey final int[] idReceived = new int[1]; 8693a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey mNotifManager.enqueueNotificationWithTag(packageName, tag, 8704120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn 0x0, builder.getNotification(), idReceived, UserHandle.USER_OWNER); 8718e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey mActiveNotifs.add(tag); 8723a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey } catch (RemoteException e) { 873b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey // ignored; service lives in system_server 8743a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey } 8753a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey } 8763a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey 8773a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey private void cancelNotification(String tag) { 878497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey // TODO: move to NotificationManager once we can mock it 8794120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn // XXX what to do about multi-user? 880497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey try { 881497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey final String packageName = mContext.getPackageName(); 8823a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey mNotifManager.cancelNotificationWithTag( 8834120375d46091df8527bb701882e056fbb0e6b06Dianne Hackborn packageName, tag, 0x0, UserHandle.USER_OWNER); 884497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey } catch (RemoteException e) { 885b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey // ignored; service lives in system_server 886497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey } 887497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey } 888497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey 889497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey /** 89021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey * Receiver that watches for {@link IConnectivityManager} to claim network 89122c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey * interfaces. Used to apply {@link NetworkPolicy} to matching networks. 89221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey */ 893b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey private BroadcastReceiver mConnReceiver = new BroadcastReceiver() { 89421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey @Override 89521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey public void onReceive(Context context, Intent intent) { 89621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey // on background handler thread, and verified CONNECTIVITY_INTERNAL 89721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey // permission above. 898684c54a2eb860062f1960f4eba6bc71aa1cfa71dJeff Sharkey 899684c54a2eb860062f1960f4eba6bc71aa1cfa71dJeff Sharkey maybeRefreshTrustedTime(); 90021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey synchronized (mRulesLock) { 90122c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey ensureActiveMobilePolicyLocked(); 9028e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey updateNetworkEnabledLocked(); 90302e21d6a5b5117d494777a36783909854854f751Jeff Sharkey updateNetworkRulesLocked(); 90402e21d6a5b5117d494777a36783909854854f751Jeff Sharkey updateNotificationsLocked(); 90521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 90621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 90721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey }; 90821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 90921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey /** 9108e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey * Proactively control network data connections when they exceed 9118e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey * {@link NetworkPolicy#limitBytes}. 9128e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey */ 9138e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey private void updateNetworkEnabledLocked() { 9148e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey if (LOGV) Slog.v(TAG, "updateNetworkEnabledLocked()"); 9158e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey 9168e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey // TODO: reset any policy-disabled networks when any policy is removed 9178e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey // completely, which is currently rare case. 9188e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey 919684c54a2eb860062f1960f4eba6bc71aa1cfa71dJeff Sharkey final long currentTime = currentTimeMillis(); 9208e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey for (NetworkPolicy policy : mNetworkPolicy.values()) { 9218e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey // shortcut when policy has no limit 9228fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey if (policy.limitBytes == LIMIT_DISABLED || !policy.hasCycle()) { 9238e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey setNetworkTemplateEnabled(policy.template, true); 9248e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey continue; 9258e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey } 9268e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey 9278e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey final long start = computeLastCycleBoundary(currentTime, policy); 9288e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey final long end = currentTime; 9298e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey final long totalBytes = getTotalBytes(policy.template, start, end); 9308e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey 9318e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey // disable data connection when over limit and not snoozed 9320e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey final boolean overLimitWithoutSnooze = policy.isOverLimit(totalBytes) 9330e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey && policy.lastLimitSnooze < start; 9340e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey final boolean networkEnabled = !overLimitWithoutSnooze; 9358e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey 9360e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey setNetworkTemplateEnabled(policy.template, networkEnabled); 9378e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey } 9388e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey } 9398e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey 9408e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey /** 9418e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey * Control {@link IConnectivityManager#setPolicyDataEnable(int, boolean)} 9428e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey * for the given {@link NetworkTemplate}. 9438e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey */ 9448e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey private void setNetworkTemplateEnabled(NetworkTemplate template, boolean enabled) { 9458fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey final TelephonyManager tele = TelephonyManager.from(mContext); 9468fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey 9478e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey switch (template.getMatchRule()) { 9488e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey case MATCH_MOBILE_3G_LOWER: 9498e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey case MATCH_MOBILE_4G: 9508e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey case MATCH_MOBILE_ALL: 9518e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey // TODO: offer more granular control over radio states once 9528e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey // 4965893 is available. 9538fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey if (tele.getSimState() == SIM_STATE_READY 9548fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey && Objects.equal(tele.getSubscriberId(), template.getSubscriberId())) { 9558e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey setPolicyDataEnable(TYPE_MOBILE, enabled); 9568e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey setPolicyDataEnable(TYPE_WIMAX, enabled); 9578e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey } 9588e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey break; 9598e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey case MATCH_WIFI: 9608e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey setPolicyDataEnable(TYPE_WIFI, enabled); 9618e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey break; 9628e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey case MATCH_ETHERNET: 9638e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey setPolicyDataEnable(TYPE_ETHERNET, enabled); 9648e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey break; 9658e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey default: 9668e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey throw new IllegalArgumentException("unexpected template"); 9678e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey } 9688e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey } 9698e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey 9708e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey /** 97121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey * Examine all connected {@link NetworkState}, looking for 97221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey * {@link NetworkPolicy} that need to be enforced. When matches found, set 97321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey * remaining quota based on usage cycle and historical stats. 97421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey */ 97502e21d6a5b5117d494777a36783909854854f751Jeff Sharkey private void updateNetworkRulesLocked() { 97622c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey if (LOGV) Slog.v(TAG, "updateIfacesLocked()"); 97721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 97821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final NetworkState[] states; 97921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey try { 98021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey states = mConnManager.getAllNetworkState(); 98121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } catch (RemoteException e) { 982b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey // ignored; service lives in system_server 98321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey return; 98421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 98521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 98621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey // first, derive identity for all connected networks, which can be used 98721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey // to match against templates. 98821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final HashMap<NetworkIdentity, String> networks = Maps.newHashMap(); 98921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey for (NetworkState state : states) { 99021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey // stash identity and iface away for later use 99121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey if (state.networkInfo.isConnected()) { 99221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final String iface = state.linkProperties.getInterfaceName(); 99321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state); 99421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey networks.put(ident, iface); 99521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 99621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 99721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 99821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey // build list of rules and ifaces to enforce them against 99902e21d6a5b5117d494777a36783909854854f751Jeff Sharkey mNetworkRules.clear(); 100021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final ArrayList<String> ifaceList = Lists.newArrayList(); 100141ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey for (NetworkPolicy policy : mNetworkPolicy.values()) { 100221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 100321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey // collect all active ifaces that match this template 100421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey ifaceList.clear(); 100547eb102b40cd1324d89816a7fb0fecd14fd7a408Jeff Sharkey for (Map.Entry<NetworkIdentity, String> entry : networks.entrySet()) { 100647eb102b40cd1324d89816a7fb0fecd14fd7a408Jeff Sharkey final NetworkIdentity ident = entry.getKey(); 10071b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey if (policy.template.matches(ident)) { 100847eb102b40cd1324d89816a7fb0fecd14fd7a408Jeff Sharkey final String iface = entry.getValue(); 100921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey ifaceList.add(iface); 101021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 101121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 101221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 101321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey if (ifaceList.size() > 0) { 101421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final String[] ifaces = ifaceList.toArray(new String[ifaceList.size()]); 101502e21d6a5b5117d494777a36783909854854f751Jeff Sharkey mNetworkRules.put(policy, ifaces); 101621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 101721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 101821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 1019ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey long lowestRule = Long.MAX_VALUE; 1020b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey final HashSet<String> newMeteredIfaces = Sets.newHashSet(); 1021fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey 102221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey // apply each policy that we found ifaces for; compute remaining data 102321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey // based on current cycle and historical stats, and push to kernel. 1024684c54a2eb860062f1960f4eba6bc71aa1cfa71dJeff Sharkey final long currentTime = currentTimeMillis(); 102502e21d6a5b5117d494777a36783909854854f751Jeff Sharkey for (NetworkPolicy policy : mNetworkRules.keySet()) { 102602e21d6a5b5117d494777a36783909854854f751Jeff Sharkey final String[] ifaces = mNetworkRules.get(policy); 102721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 10288fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey final long start; 10298fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey final long totalBytes; 10308fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey if (policy.hasCycle()) { 10318fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey start = computeLastCycleBoundary(currentTime, policy); 10328fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey totalBytes = getTotalBytes(policy.template, start, currentTime); 10338fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey } else { 10348fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey start = Long.MAX_VALUE; 10358fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey totalBytes = 0; 10368fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey } 103721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 103821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey if (LOGD) { 103921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey Slog.d(TAG, "applying policy " + policy.toString() + " to ifaces " 104022c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey + Arrays.toString(ifaces)); 104122c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey } 104222c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey 1043ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey final boolean hasWarning = policy.warningBytes != LIMIT_DISABLED; 104441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey final boolean hasLimit = policy.limitBytes != LIMIT_DISABLED; 1045f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey if (hasLimit || policy.metered) { 10468e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey final long quotaBytes; 1047f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey if (!hasLimit) { 1048f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey // metered network, but no policy limit; we still need to 1049f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey // restrict apps, so push really high quota. 1050f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey quotaBytes = Long.MAX_VALUE; 10510e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey } else if (policy.lastLimitSnooze >= start) { 10528e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey // snoozing past quota, but we still need to restrict apps, 10538e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey // so push really high quota. 10548e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey quotaBytes = Long.MAX_VALUE; 10558e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey } else { 10568e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey // remaining "quota" bytes are based on total usage in 10578e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey // current cycle. kernel doesn't like 0-byte rules, so we 10588e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey // set 1-byte quota and disable the radio later. 10598e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey quotaBytes = Math.max(1, policy.limitBytes - totalBytes); 10608e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey } 106150fd36d7c38c40b087c8f3e3172478abe0c051d9Ashish Sharma 1062b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey if (ifaces.length > 1) { 1063b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey // TODO: switch to shared quota once NMS supports 1064b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey Slog.w(TAG, "shared quota unsupported; generating rule for each iface"); 1065b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey } 1066fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey 1067fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey for (String iface : ifaces) { 1068b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey removeInterfaceQuota(iface); 10698e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey setInterfaceQuota(iface, quotaBytes); 10708e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey newMeteredIfaces.add(iface); 107141ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey } 107241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey } 1073ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey 1074ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey // keep track of lowest warning or limit of active policies 1075ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey if (hasWarning && policy.warningBytes < lowestRule) { 1076ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey lowestRule = policy.warningBytes; 1077ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey } 1078ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey if (hasLimit && policy.limitBytes < lowestRule) { 1079ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey lowestRule = policy.limitBytes; 1080ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey } 1081ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey } 1082ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey 1083e19f39b79c831aea4d51a3309025acdf69d1e609Jeff Sharkey mHandler.obtainMessage(MSG_ADVISE_PERSIST_THRESHOLD, lowestRule).sendToTarget(); 1084fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey 1085b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey // remove quota on any trailing interfaces 1086b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey for (String iface : mMeteredIfaces) { 1087b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey if (!newMeteredIfaces.contains(iface)) { 1088b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey removeInterfaceQuota(iface); 108950fd36d7c38c40b087c8f3e3172478abe0c051d9Ashish Sharma } 109050fd36d7c38c40b087c8f3e3172478abe0c051d9Ashish Sharma } 1091b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey mMeteredIfaces = newMeteredIfaces; 1092b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey 1093b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey final String[] meteredIfaces = mMeteredIfaces.toArray(new String[mMeteredIfaces.size()]); 1094b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey mHandler.obtainMessage(MSG_METERED_IFACES_CHANGED, meteredIfaces).sendToTarget(); 109550fd36d7c38c40b087c8f3e3172478abe0c051d9Ashish Sharma } 109650fd36d7c38c40b087c8f3e3172478abe0c051d9Ashish Sharma 109722c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey /** 109822c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey * Once any {@link #mNetworkPolicy} are loaded from disk, ensure that we 109922c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey * have at least a default mobile policy defined. 110022c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey */ 110122c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey private void ensureActiveMobilePolicyLocked() { 110222c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey if (LOGV) Slog.v(TAG, "ensureActiveMobilePolicyLocked()"); 11038e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey if (mSuppressDefaultPolicy) return; 11048e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey 11058fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey final TelephonyManager tele = TelephonyManager.from(mContext); 11068fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey 11078fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey // avoid creating policy when SIM isn't ready 11088fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey if (tele.getSimState() != SIM_STATE_READY) return; 11098fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey 11108fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey final String subscriberId = tele.getSubscriberId(); 11111b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey final NetworkIdentity probeIdent = new NetworkIdentity( 11128fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false); 111322c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey 111422c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey // examine to see if any policy is defined for active mobile 111522c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey boolean mobileDefined = false; 111641ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey for (NetworkPolicy policy : mNetworkPolicy.values()) { 11171b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey if (policy.template.matches(probeIdent)) { 111822c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey mobileDefined = true; 111921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 112022c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey } 112121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 112222c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey if (!mobileDefined) { 112322c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey Slog.i(TAG, "no policy for active mobile network; generating default policy"); 112421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 112502e21d6a5b5117d494777a36783909854854f751Jeff Sharkey // build default mobile policy, and assume usage cycle starts today 112602e21d6a5b5117d494777a36783909854854f751Jeff Sharkey final long warningBytes = mContext.getResources().getInteger( 112702e21d6a5b5117d494777a36783909854854f751Jeff Sharkey com.android.internal.R.integer.config_networkPolicyDefaultWarning) 112802e21d6a5b5117d494777a36783909854854f751Jeff Sharkey * MB_IN_BYTES; 112922c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey 11309bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey final Time time = new Time(); 113122c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey time.setToNow(); 11329bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey 113322c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey final int cycleDay = time.monthDay; 11349bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey final String cycleTimezone = time.timezone; 113522c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey 11364e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey final NetworkTemplate template = buildTemplateMobileAll(subscriberId); 11379f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey final NetworkPolicy policy = new NetworkPolicy(template, cycleDay, cycleTimezone, 11389f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey warningBytes, LIMIT_DISABLED, SNOOZE_NEVER, SNOOZE_NEVER, true, true); 11399f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey addNetworkPolicyLocked(policy); 114021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 114121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 114221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 114321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private void readPolicyLocked() { 114422c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey if (LOGV) Slog.v(TAG, "readPolicyLocked()"); 114521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 114621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey // clear any existing policy and read from disk 114722c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey mNetworkPolicy.clear(); 1148d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey mUidPolicy.clear(); 114921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 115021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey FileInputStream fis = null; 115121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey try { 115221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey fis = mPolicyFile.openRead(); 115321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final XmlPullParser in = Xml.newPullParser(); 115421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey in.setInput(fis, null); 115521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 115621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey int type; 115741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey int version = VERSION_INIT; 115821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey while ((type = in.next()) != END_DOCUMENT) { 115921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final String tag = in.getName(); 116021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey if (type == START_TAG) { 116121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey if (TAG_POLICY_LIST.equals(tag)) { 116221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey version = readIntAttribute(in, ATTR_VERSION); 11634664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey if (version >= VERSION_ADDED_RESTRICT_BACKGROUND) { 11644664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey mRestrictBackground = readBooleanAttribute( 11654664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey in, ATTR_RESTRICT_BACKGROUND); 11664664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey } else { 11673a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey mRestrictBackground = false; 11684664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey } 116921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 117021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } else if (TAG_NETWORK_POLICY.equals(tag)) { 117121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final int networkTemplate = readIntAttribute(in, ATTR_NETWORK_TEMPLATE); 117221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final String subscriberId = in.getAttributeValue(null, ATTR_SUBSCRIBER_ID); 11738fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey final String networkId; 11748fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey if (version >= VERSION_ADDED_NETWORK_ID) { 11758fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey networkId = in.getAttributeValue(null, ATTR_NETWORK_ID); 11768fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey } else { 11778fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey networkId = null; 11788fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey } 117921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final int cycleDay = readIntAttribute(in, ATTR_CYCLE_DAY); 11809bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey final String cycleTimezone; 11819bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey if (version >= VERSION_ADDED_TIMEZONE) { 11829bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey cycleTimezone = in.getAttributeValue(null, ATTR_CYCLE_TIMEZONE); 11839bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey } else { 11849bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey cycleTimezone = Time.TIMEZONE_UTC; 11859bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey } 118621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final long warningBytes = readLongAttribute(in, ATTR_WARNING_BYTES); 118721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final long limitBytes = readLongAttribute(in, ATTR_LIMIT_BYTES); 11880e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey final long lastLimitSnooze; 11890e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey if (version >= VERSION_SPLIT_SNOOZE) { 11900e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey lastLimitSnooze = readLongAttribute(in, ATTR_LAST_LIMIT_SNOOZE); 11910e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey } else if (version >= VERSION_ADDED_SNOOZE) { 11920e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey lastLimitSnooze = readLongAttribute(in, ATTR_LAST_SNOOZE); 119341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey } else { 11940e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey lastLimitSnooze = SNOOZE_NEVER; 119541ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey } 1196f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey final boolean metered; 1197f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey if (version >= VERSION_ADDED_METERED) { 1198f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey metered = readBooleanAttribute(in, ATTR_METERED); 1199f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey } else { 1200f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey switch (networkTemplate) { 1201f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey case MATCH_MOBILE_3G_LOWER: 1202f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey case MATCH_MOBILE_4G: 1203f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey case MATCH_MOBILE_ALL: 1204f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey metered = true; 1205f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey break; 1206f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey default: 1207f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey metered = false; 1208f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey } 1209f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey } 12100e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey final long lastWarningSnooze; 12110e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey if (version >= VERSION_SPLIT_SNOOZE) { 12120e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey lastWarningSnooze = readLongAttribute(in, ATTR_LAST_WARNING_SNOOZE); 12130e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey } else { 12140e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey lastWarningSnooze = SNOOZE_NEVER; 12150e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey } 1216837f9242ae2e8f5f380d0b30b8fffbc68494914fJeff Sharkey final boolean inferred; 1217837f9242ae2e8f5f380d0b30b8fffbc68494914fJeff Sharkey if (version >= VERSION_ADDED_INFERRED) { 1218837f9242ae2e8f5f380d0b30b8fffbc68494914fJeff Sharkey inferred = readBooleanAttribute(in, ATTR_INFERRED); 1219837f9242ae2e8f5f380d0b30b8fffbc68494914fJeff Sharkey } else { 1220837f9242ae2e8f5f380d0b30b8fffbc68494914fJeff Sharkey inferred = false; 1221837f9242ae2e8f5f380d0b30b8fffbc68494914fJeff Sharkey } 122221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 12231b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey final NetworkTemplate template = new NetworkTemplate( 12248fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey networkTemplate, subscriberId, networkId); 12250e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey mNetworkPolicy.put(template, new NetworkPolicy(template, cycleDay, 12269bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey cycleTimezone, warningBytes, limitBytes, lastWarningSnooze, 1227837f9242ae2e8f5f380d0b30b8fffbc68494914fJeff Sharkey lastLimitSnooze, metered, inferred)); 122821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 1229d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey } else if (TAG_UID_POLICY.equals(tag)) { 123021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final int uid = readIntAttribute(in, ATTR_UID); 123121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final int policy = readIntAttribute(in, ATTR_POLICY); 123221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 1233d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey if (UserHandle.isApp(uid)) { 1234d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey setUidPolicyUnchecked(uid, policy, false); 1235497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey } else { 1236497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey Slog.w(TAG, "unable to apply policy to UID " + uid + "; ignoring"); 1237497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey } 1238d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey } else if (TAG_APP_POLICY.equals(tag)) { 12398a8b581e669f6187b397f856a567a76ed8aba2c2Jeff Sharkey final int appId = readIntAttribute(in, ATTR_APP_ID); 12408a8b581e669f6187b397f856a567a76ed8aba2c2Jeff Sharkey final int policy = readIntAttribute(in, ATTR_POLICY); 12418a8b581e669f6187b397f856a567a76ed8aba2c2Jeff Sharkey 1242d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey // TODO: set for other users during upgrade 1243d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey final int uid = UserHandle.getUid(UserHandle.USER_OWNER, appId); 1244d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey if (UserHandle.isApp(uid)) { 1245d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey setUidPolicyUnchecked(uid, policy, false); 12468a8b581e669f6187b397f856a567a76ed8aba2c2Jeff Sharkey } else { 1247d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey Slog.w(TAG, "unable to apply policy to UID " + uid + "; ignoring"); 12488a8b581e669f6187b397f856a567a76ed8aba2c2Jeff Sharkey } 124921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 125021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 125121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 125221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 125321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } catch (FileNotFoundException e) { 125421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey // missing policy is okay, probably first boot 12553a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey upgradeLegacyBackgroundData(); 125621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } catch (IOException e) { 1257b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey Log.wtf(TAG, "problem reading network policy", e); 125821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } catch (XmlPullParserException e) { 1259b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey Log.wtf(TAG, "problem reading network policy", e); 126021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } finally { 126121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey IoUtils.closeQuietly(fis); 126221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 126321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 126421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 12653a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey /** 12663a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey * Upgrade legacy background data flags, notifying listeners of one last 12673a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey * change to always-true. 12683a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey */ 12693a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey private void upgradeLegacyBackgroundData() { 12703a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey mRestrictBackground = Settings.Secure.getInt( 12713a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey mContext.getContentResolver(), Settings.Secure.BACKGROUND_DATA, 1) != 1; 12723a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey 12733a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey // kick off one last broadcast if restricted 12743a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey if (mRestrictBackground) { 12753a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey final Intent broadcast = new Intent( 12763a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey ConnectivityManager.ACTION_BACKGROUND_DATA_SETTING_CHANGED); 12775ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackborn mContext.sendBroadcastAsUser(broadcast, UserHandle.ALL); 12783a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey } 12793a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey } 12803a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey 128121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private void writePolicyLocked() { 128222c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey if (LOGV) Slog.v(TAG, "writePolicyLocked()"); 128321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 128421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey FileOutputStream fos = null; 128521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey try { 128621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey fos = mPolicyFile.startWrite(); 128721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 128821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey XmlSerializer out = new FastXmlSerializer(); 128921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey out.setOutput(fos, "utf-8"); 129021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey out.startDocument(null, true); 129121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 129221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey out.startTag(null, TAG_POLICY_LIST); 12938fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey writeIntAttribute(out, ATTR_VERSION, VERSION_LATEST); 12944664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey writeBooleanAttribute(out, ATTR_RESTRICT_BACKGROUND, mRestrictBackground); 129521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 129621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey // write all known network policies 129741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey for (NetworkPolicy policy : mNetworkPolicy.values()) { 12981b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey final NetworkTemplate template = policy.template; 12991b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey 130021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey out.startTag(null, TAG_NETWORK_POLICY); 13011b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey writeIntAttribute(out, ATTR_NETWORK_TEMPLATE, template.getMatchRule()); 13021b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey final String subscriberId = template.getSubscriberId(); 13031b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey if (subscriberId != null) { 13041b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey out.attribute(null, ATTR_SUBSCRIBER_ID, subscriberId); 130521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 13068fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey final String networkId = template.getNetworkId(); 13078fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey if (networkId != null) { 13088fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey out.attribute(null, ATTR_NETWORK_ID, networkId); 13098fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey } 131021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey writeIntAttribute(out, ATTR_CYCLE_DAY, policy.cycleDay); 13119bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey out.attribute(null, ATTR_CYCLE_TIMEZONE, policy.cycleTimezone); 131221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey writeLongAttribute(out, ATTR_WARNING_BYTES, policy.warningBytes); 131321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey writeLongAttribute(out, ATTR_LIMIT_BYTES, policy.limitBytes); 13140e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey writeLongAttribute(out, ATTR_LAST_WARNING_SNOOZE, policy.lastWarningSnooze); 13150e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey writeLongAttribute(out, ATTR_LAST_LIMIT_SNOOZE, policy.lastLimitSnooze); 1316f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey writeBooleanAttribute(out, ATTR_METERED, policy.metered); 1317837f9242ae2e8f5f380d0b30b8fffbc68494914fJeff Sharkey writeBooleanAttribute(out, ATTR_INFERRED, policy.inferred); 131821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey out.endTag(null, TAG_NETWORK_POLICY); 131921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 132021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 132121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey // write all known uid policies 1322d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey for (int i = 0; i < mUidPolicy.size(); i++) { 1323d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey final int uid = mUidPolicy.keyAt(i); 1324d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey final int policy = mUidPolicy.valueAt(i); 132521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 1326497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey // skip writing empty policies 1327497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey if (policy == POLICY_NONE) continue; 1328497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey 1329d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey out.startTag(null, TAG_UID_POLICY); 1330d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey writeIntAttribute(out, ATTR_UID, uid); 133121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey writeIntAttribute(out, ATTR_POLICY, policy); 1332d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey out.endTag(null, TAG_UID_POLICY); 133321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 133421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 133521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey out.endTag(null, TAG_POLICY_LIST); 133621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey out.endDocument(); 133721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 133821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey mPolicyFile.finishWrite(fos); 133921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } catch (IOException e) { 134021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey if (fos != null) { 134121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey mPolicyFile.failWrite(fos); 134221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 134321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 134421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 134521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 1346d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey @Override 1347d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey public void setUidPolicy(int uid, int policy) { 134821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 1349a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey 1350d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey if (!UserHandle.isApp(uid)) { 1351d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey throw new IllegalArgumentException("cannot apply policy to UID " + uid); 1352497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey } 1353497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey 1354d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey setUidPolicyUnchecked(uid, policy, true); 1355497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey } 1356497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey 1357d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey private void setUidPolicyUnchecked(int uid, int policy, boolean persist) { 1358c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey final int oldPolicy; 1359a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey synchronized (mRulesLock) { 1360d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey oldPolicy = getUidPolicy(uid); 1361d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey mUidPolicy.put(uid, policy); 1362c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey 136321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey // uid policy changed, recompute rules and persist policy. 1364d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey updateRulesForUidLocked(uid); 1365497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey if (persist) { 1366497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey writePolicyLocked(); 1367497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey } 136821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 1369d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey } 1370d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 1371d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey @Override 1372d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey public int getUidPolicy(int uid) { 137321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 137421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 1375a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey synchronized (mRulesLock) { 1376d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey return mUidPolicy.get(uid, POLICY_NONE); 1377a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 1378d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey } 1379d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 1380c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey @Override 1381d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey public int[] getUidsWithPolicy(int policy) { 1382854b2b1670bda1eeb87a14b7ac3d222024f0aad6Jeff Sharkey mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 1383854b2b1670bda1eeb87a14b7ac3d222024f0aad6Jeff Sharkey 1384d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey int[] uids = new int[0]; 1385854b2b1670bda1eeb87a14b7ac3d222024f0aad6Jeff Sharkey synchronized (mRulesLock) { 1386d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey for (int i = 0; i < mUidPolicy.size(); i++) { 1387d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey final int uid = mUidPolicy.keyAt(i); 1388d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey final int uidPolicy = mUidPolicy.valueAt(i); 1389d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey if (uidPolicy == policy) { 1390d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey uids = appendInt(uids, uid); 1391854b2b1670bda1eeb87a14b7ac3d222024f0aad6Jeff Sharkey } 1392854b2b1670bda1eeb87a14b7ac3d222024f0aad6Jeff Sharkey } 1393854b2b1670bda1eeb87a14b7ac3d222024f0aad6Jeff Sharkey } 1394d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey return uids; 1395d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey } 1396d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey 1397d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey /** 1398d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey * Remove any policies associated with given {@link UserHandle}, persisting 1399d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey * if any changes are made. 1400d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey */ 1401d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey private void removePoliciesForUserLocked(int userId) { 1402d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey if (LOGV) Slog.v(TAG, "removePoliciesForUserLocked()"); 1403d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey 1404d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey int[] uids = new int[0]; 1405d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey for (int i = 0; i < mUidPolicy.size(); i++) { 1406d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey final int uid = mUidPolicy.keyAt(i); 1407d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey if (UserHandle.getUserId(uid) == userId) { 1408d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey uids = appendInt(uids, uid); 1409d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey } 1410d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey } 1411d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey 1412d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey if (uids.length > 0) { 1413d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey for (int uid : uids) { 1414d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey mUidPolicy.delete(uid); 1415d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey updateRulesForUidLocked(uid); 1416d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey } 1417d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey writePolicyLocked(); 1418d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey } 1419854b2b1670bda1eeb87a14b7ac3d222024f0aad6Jeff Sharkey } 1420854b2b1670bda1eeb87a14b7ac3d222024f0aad6Jeff Sharkey 1421854b2b1670bda1eeb87a14b7ac3d222024f0aad6Jeff Sharkey @Override 1422c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey public void registerListener(INetworkPolicyListener listener) { 14231a303953589fdddf21d88b8fa660136f5b060d0dJeff Sharkey // TODO: create permission for observing network policy 14241a303953589fdddf21d88b8fa660136f5b060d0dJeff Sharkey mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 14251a303953589fdddf21d88b8fa660136f5b060d0dJeff Sharkey 1426c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey mListeners.register(listener); 1427c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey 14284414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey // TODO: consider dispatching existing rules to new listeners 1429c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey } 1430c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey 1431c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey @Override 1432c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey public void unregisterListener(INetworkPolicyListener listener) { 14331a303953589fdddf21d88b8fa660136f5b060d0dJeff Sharkey // TODO: create permission for observing network policy 14341a303953589fdddf21d88b8fa660136f5b060d0dJeff Sharkey mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 14351a303953589fdddf21d88b8fa660136f5b060d0dJeff Sharkey 1436c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey mListeners.unregister(listener); 1437c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey } 1438c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey 14391b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey @Override 144022c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey public void setNetworkPolicies(NetworkPolicy[] policies) { 144121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 144221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 1443684c54a2eb860062f1960f4eba6bc71aa1cfa71dJeff Sharkey maybeRefreshTrustedTime(); 144421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey synchronized (mRulesLock) { 144522c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey mNetworkPolicy.clear(); 144622c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey for (NetworkPolicy policy : policies) { 144741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey mNetworkPolicy.put(policy.template, policy); 144822c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey } 144921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 14508e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey updateNetworkEnabledLocked(); 145102e21d6a5b5117d494777a36783909854854f751Jeff Sharkey updateNetworkRulesLocked(); 1452497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey updateNotificationsLocked(); 145321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey writePolicyLocked(); 145421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 145521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 145621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 14579f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey private void addNetworkPolicyLocked(NetworkPolicy policy) { 14589f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey mNetworkPolicy.put(policy.template, policy); 14599f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey 14609f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey updateNetworkEnabledLocked(); 14619f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey updateNetworkRulesLocked(); 14629f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey updateNotificationsLocked(); 14639f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey writePolicyLocked(); 14649f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey } 14659f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey 146621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey @Override 146722c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey public NetworkPolicy[] getNetworkPolicies() { 146821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 146922c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, TAG); 147021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 147121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey synchronized (mRulesLock) { 147241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey return mNetworkPolicy.values().toArray(new NetworkPolicy[mNetworkPolicy.size()]); 147341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey } 147441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey } 147541ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey 147641ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey @Override 14770e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey public void snoozeLimit(NetworkTemplate template) { 147841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 14796c0b4f393ae8e728c7a7943bfbdcdd27d6642192Jeff Sharkey 14806c0b4f393ae8e728c7a7943bfbdcdd27d6642192Jeff Sharkey final long token = Binder.clearCallingIdentity(); 14816c0b4f393ae8e728c7a7943bfbdcdd27d6642192Jeff Sharkey try { 14826c0b4f393ae8e728c7a7943bfbdcdd27d6642192Jeff Sharkey performSnooze(template, TYPE_LIMIT); 14836c0b4f393ae8e728c7a7943bfbdcdd27d6642192Jeff Sharkey } finally { 14846c0b4f393ae8e728c7a7943bfbdcdd27d6642192Jeff Sharkey Binder.restoreCallingIdentity(token); 14856c0b4f393ae8e728c7a7943bfbdcdd27d6642192Jeff Sharkey } 14860e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey } 148741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey 14880e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey private void performSnooze(NetworkTemplate template, int type) { 1489684c54a2eb860062f1960f4eba6bc71aa1cfa71dJeff Sharkey maybeRefreshTrustedTime(); 1490684c54a2eb860062f1960f4eba6bc71aa1cfa71dJeff Sharkey final long currentTime = currentTimeMillis(); 149141ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey synchronized (mRulesLock) { 149241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey // find and snooze local policy that matches 149341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey final NetworkPolicy policy = mNetworkPolicy.get(template); 149441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey if (policy == null) { 149541ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey throw new IllegalArgumentException("unable to find policy for " + template); 149641ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey } 149741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey 14980e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey switch (type) { 14990e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey case TYPE_WARNING: 15000e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey policy.lastWarningSnooze = currentTime; 15010e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey break; 15020e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey case TYPE_LIMIT: 15030e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey policy.lastLimitSnooze = currentTime; 15040e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey break; 15050e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey default: 15060e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey throw new IllegalArgumentException("unexpected type"); 15070e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey } 150841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey 15098e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey updateNetworkEnabledLocked(); 151041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey updateNetworkRulesLocked(); 151141ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey updateNotificationsLocked(); 151241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey writePolicyLocked(); 151321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 151421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 151521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 151621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey @Override 15174664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey public void setRestrictBackground(boolean restrictBackground) { 15184664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 15194664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey 1520684c54a2eb860062f1960f4eba6bc71aa1cfa71dJeff Sharkey maybeRefreshTrustedTime(); 15214664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey synchronized (mRulesLock) { 15224664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey mRestrictBackground = restrictBackground; 15234664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey updateRulesForRestrictBackgroundLocked(); 15243a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey updateNotificationsLocked(); 1525f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey writePolicyLocked(); 15264664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey } 15271f8ea2dcd1ed3cde4b84fbb27b5a55b3fea7ff2aJeff Sharkey 15281f8ea2dcd1ed3cde4b84fbb27b5a55b3fea7ff2aJeff Sharkey mHandler.obtainMessage(MSG_RESTRICT_BACKGROUND_CHANGED, restrictBackground ? 1 : 0, 0) 15291f8ea2dcd1ed3cde4b84fbb27b5a55b3fea7ff2aJeff Sharkey .sendToTarget(); 15304664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey } 15314664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey 15324664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey @Override 15334664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey public boolean getRestrictBackground() { 15344664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 15354664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey 15364664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey synchronized (mRulesLock) { 15374664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey return mRestrictBackground; 15384664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey } 15394664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey } 15404664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey 1541f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey private NetworkPolicy findPolicyForNetworkLocked(NetworkIdentity ident) { 1542f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey for (NetworkPolicy policy : mNetworkPolicy.values()) { 1543f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey if (policy.template.matches(ident)) { 1544f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey return policy; 1545f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey } 1546f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey } 1547f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey return null; 1548f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey } 1549f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey 1550f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey @Override 1551f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey public NetworkQuotaInfo getNetworkQuotaInfo(NetworkState state) { 1552f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG); 1553f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey 1554f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey // only returns usage summary, so we don't require caller to have 1555f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey // READ_NETWORK_USAGE_HISTORY. 1556f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey final long token = Binder.clearCallingIdentity(); 1557f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey try { 1558f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey return getNetworkQuotaInfoUnchecked(state); 1559f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey } finally { 1560f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey Binder.restoreCallingIdentity(token); 1561f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey } 1562f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey } 1563f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey 1564f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey private NetworkQuotaInfo getNetworkQuotaInfoUnchecked(NetworkState state) { 1565f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state); 1566f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey 1567f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey final NetworkPolicy policy; 1568f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey synchronized (mRulesLock) { 1569f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey policy = findPolicyForNetworkLocked(ident); 1570f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey } 1571f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey 15728fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey if (policy == null || !policy.hasCycle()) { 1573f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey // missing policy means we can't derive useful quota info 1574f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey return null; 1575f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey } 1576f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey 1577684c54a2eb860062f1960f4eba6bc71aa1cfa71dJeff Sharkey final long currentTime = currentTimeMillis(); 1578f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey 1579b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey // find total bytes used under policy 1580f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey final long start = computeLastCycleBoundary(currentTime, policy); 1581f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey final long end = currentTime; 15828e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey final long totalBytes = getTotalBytes(policy.template, start, end); 1583f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey 1584f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey // report soft and hard limits under policy 1585f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey final long softLimitBytes = policy.warningBytes != WARNING_DISABLED ? policy.warningBytes 1586f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey : NetworkQuotaInfo.NO_LIMIT; 1587f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey final long hardLimitBytes = policy.limitBytes != LIMIT_DISABLED ? policy.limitBytes 1588f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey : NetworkQuotaInfo.NO_LIMIT; 1589f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey 1590f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey return new NetworkQuotaInfo(totalBytes, softLimitBytes, hardLimitBytes); 1591f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey } 1592f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey 15934664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey @Override 15949f7cbf0e50bcb7e9163b23524814003ba8784732Jeff Sharkey public boolean isNetworkMetered(NetworkState state) { 15959f7cbf0e50bcb7e9163b23524814003ba8784732Jeff Sharkey final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state); 15969f7cbf0e50bcb7e9163b23524814003ba8784732Jeff Sharkey 1597f166f480f0f29b310a27fe001ee26d7dfac84fddJeff Sharkey // roaming networks are always considered metered 1598f166f480f0f29b310a27fe001ee26d7dfac84fddJeff Sharkey if (ident.getRoaming()) { 1599f166f480f0f29b310a27fe001ee26d7dfac84fddJeff Sharkey return true; 1600f166f480f0f29b310a27fe001ee26d7dfac84fddJeff Sharkey } 1601f166f480f0f29b310a27fe001ee26d7dfac84fddJeff Sharkey 16029f7cbf0e50bcb7e9163b23524814003ba8784732Jeff Sharkey final NetworkPolicy policy; 16039f7cbf0e50bcb7e9163b23524814003ba8784732Jeff Sharkey synchronized (mRulesLock) { 16049f7cbf0e50bcb7e9163b23524814003ba8784732Jeff Sharkey policy = findPolicyForNetworkLocked(ident); 16059f7cbf0e50bcb7e9163b23524814003ba8784732Jeff Sharkey } 16069f7cbf0e50bcb7e9163b23524814003ba8784732Jeff Sharkey 16079f7cbf0e50bcb7e9163b23524814003ba8784732Jeff Sharkey if (policy != null) { 16089f7cbf0e50bcb7e9163b23524814003ba8784732Jeff Sharkey return policy.metered; 16099f7cbf0e50bcb7e9163b23524814003ba8784732Jeff Sharkey } else { 16109f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey final int type = state.networkInfo.getType(); 16119f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey if (isNetworkTypeMobile(type) || type == TYPE_WIMAX) { 16129f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey return true; 16139f6e4ba50e7e73704c7fbd3ba65fe73bdf8ad73fJeff Sharkey } 16149f7cbf0e50bcb7e9163b23524814003ba8784732Jeff Sharkey return false; 16159f7cbf0e50bcb7e9163b23524814003ba8784732Jeff Sharkey } 16169f7cbf0e50bcb7e9163b23524814003ba8784732Jeff Sharkey } 16179f7cbf0e50bcb7e9163b23524814003ba8784732Jeff Sharkey 16189f7cbf0e50bcb7e9163b23524814003ba8784732Jeff Sharkey @Override 16198fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) { 162075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey mContext.enforceCallingOrSelfPermission(DUMP, TAG); 16211b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey 16228fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey final IndentingPrintWriter fout = new IndentingPrintWriter(writer, " "); 16238fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey 162441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey final HashSet<String> argSet = new HashSet<String>(); 162541ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey for (String arg : args) { 162641ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey argSet.add(arg); 162741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey } 162841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey 16291b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey synchronized (mRulesLock) { 16300e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey if (argSet.contains("--unsnooze")) { 163141ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey for (NetworkPolicy policy : mNetworkPolicy.values()) { 16320e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey policy.clearSnooze(); 163341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey } 16340e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey 16350e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey updateNetworkEnabledLocked(); 16360e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey updateNetworkRulesLocked(); 16370e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey updateNotificationsLocked(); 163841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey writePolicyLocked(); 16390e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey 16400e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey fout.println("Cleared snooze timestamps"); 164141ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey return; 164241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey } 164341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey 16444664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey fout.print("Restrict background: "); fout.println(mRestrictBackground); 164521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey fout.println("Network policies:"); 16468fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey fout.increaseIndent(); 164741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey for (NetworkPolicy policy : mNetworkPolicy.values()) { 16488fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey fout.println(policy.toString()); 164921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 16508fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey fout.decreaseIndent(); 165121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 1652d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey fout.println("Policy for UIDs:"); 16538fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey fout.increaseIndent(); 1654d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey int size = mUidPolicy.size(); 16558a8b581e669f6187b397f856a567a76ed8aba2c2Jeff Sharkey for (int i = 0; i < size; i++) { 1656d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey final int uid = mUidPolicy.keyAt(i); 1657d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey final int policy = mUidPolicy.valueAt(i); 1658d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey fout.print("UID="); 1659d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey fout.print(uid); 16608a8b581e669f6187b397f856a567a76ed8aba2c2Jeff Sharkey fout.print(" policy="); 16618a8b581e669f6187b397f856a567a76ed8aba2c2Jeff Sharkey dumpPolicy(fout, policy); 16628a8b581e669f6187b397f856a567a76ed8aba2c2Jeff Sharkey fout.println(); 16638a8b581e669f6187b397f856a567a76ed8aba2c2Jeff Sharkey } 16648fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey fout.decreaseIndent(); 16651b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey 16661b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey final SparseBooleanArray knownUids = new SparseBooleanArray(); 16671b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey collectKeys(mUidForeground, knownUids); 16681b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey collectKeys(mUidRules, knownUids); 16691b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey 16708a8b581e669f6187b397f856a567a76ed8aba2c2Jeff Sharkey fout.println("Status for known UIDs:"); 16718fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey fout.increaseIndent(); 16728a8b581e669f6187b397f856a567a76ed8aba2c2Jeff Sharkey size = knownUids.size(); 16731b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey for (int i = 0; i < size; i++) { 16741b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey final int uid = knownUids.keyAt(i); 16758fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey fout.print("UID="); 16761b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey fout.print(uid); 16771b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey 16781b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey fout.print(" foreground="); 16791b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey final int foregroundIndex = mUidPidForeground.indexOfKey(uid); 16801b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey if (foregroundIndex < 0) { 16811b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey fout.print("UNKNOWN"); 16821b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } else { 16831b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey dumpSparseBooleanArray(fout, mUidPidForeground.valueAt(foregroundIndex)); 16841b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } 16851b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey 16861b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey fout.print(" rules="); 16871b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey final int rulesIndex = mUidRules.indexOfKey(uid); 16881b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey if (rulesIndex < 0) { 16891b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey fout.print("UNKNOWN"); 16901b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } else { 16911b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey dumpRules(fout, mUidRules.valueAt(rulesIndex)); 16921b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } 16931b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey 16941b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey fout.println(); 16951b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } 16968fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey fout.decreaseIndent(); 16971b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } 16981b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } 16999599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey 17009599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey @Override 17019599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey public boolean isUidForeground(int uid) { 1702497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 1703497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey 17049599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey synchronized (mRulesLock) { 17059599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey // only really in foreground when screen is also on 17069599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey return mUidForeground.get(uid, false) && mScreenOn; 17079599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey } 1708c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey } 1709c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey 1710d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey /** 1711d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey * Foreground for PID changed; recompute foreground at UID level. If 171221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey * changed, will trigger {@link #updateRulesForUidLocked(int)}. 1713d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey */ 171421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private void computeUidForegroundLocked(int uid) { 1715d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey final SparseBooleanArray pidForeground = mUidPidForeground.get(uid); 1716d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 1717d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey // current pid is dropping foreground; examine other pids 1718d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey boolean uidForeground = false; 1719d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey final int size = pidForeground.size(); 1720d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey for (int i = 0; i < size; i++) { 1721d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey if (pidForeground.valueAt(i)) { 1722d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey uidForeground = true; 1723d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey break; 1724d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey } 1725d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey } 1726d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 1727d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey final boolean oldUidForeground = mUidForeground.get(uid, false); 1728d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey if (oldUidForeground != uidForeground) { 1729d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey // foreground changed, push updated rules 1730d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey mUidForeground.put(uid, uidForeground); 173121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey updateRulesForUidLocked(uid); 1732a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 1733a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 1734a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey 1735a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey private void updateScreenOn() { 1736a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey synchronized (mRulesLock) { 1737a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey try { 1738a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey mScreenOn = mPowerManager.isScreenOn(); 1739a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } catch (RemoteException e) { 1740b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey // ignored; service lives in system_server 1741a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 174221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey updateRulesForScreenLocked(); 1743d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey } 1744d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey } 1745d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 1746a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey /** 1747a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey * Update rules that might be changed by {@link #mScreenOn} value. 1748a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey */ 174921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private void updateRulesForScreenLocked() { 1750a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey // only update rules for anyone with foreground activities 1751a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey final int size = mUidForeground.size(); 1752a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey for (int i = 0; i < size; i++) { 1753a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey if (mUidForeground.valueAt(i)) { 1754a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey final int uid = mUidForeground.keyAt(i); 175521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey updateRulesForUidLocked(uid); 1756a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 1757a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 1758a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey } 1759a4620793038b9a9163b26c6ece882cb454fcbf87Jeff Sharkey 1760b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey /** 17614664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey * Update rules that might be changed by {@link #mRestrictBackground} value. 1762b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey */ 17634664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey private void updateRulesForRestrictBackgroundLocked() { 1764b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey final PackageManager pm = mContext.getPackageManager(); 1765d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey final UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE); 1766d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey 1767d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey // update rules for all installed applications 1768d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey final List<UserInfo> users = um.getUsers(); 1769d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey final List<ApplicationInfo> apps = pm.getInstalledApplications( 1770d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey PackageManager.GET_UNINSTALLED_PACKAGES | PackageManager.GET_DISABLED_COMPONENTS); 1771d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey 1772d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey for (UserInfo user : users) { 1773d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey for (ApplicationInfo app : apps) { 1774d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey final int uid = UserHandle.getUid(user.id, app.uid); 1775d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey updateRulesForUidLocked(uid); 1776d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey } 1777b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey } 1778b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey 17795294a2fc2f401cd248a4bc3f0f9ee1e2854f4e9aJeff Sharkey // limit data usage for some internal system services 17805294a2fc2f401cd248a4bc3f0f9ee1e2854f4e9aJeff Sharkey updateRulesForUidLocked(android.os.Process.MEDIA_UID); 17815294a2fc2f401cd248a4bc3f0f9ee1e2854f4e9aJeff Sharkey updateRulesForUidLocked(android.os.Process.DRM_UID); 1782b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey } 1783b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey 17845294a2fc2f401cd248a4bc3f0f9ee1e2854f4e9aJeff Sharkey private static boolean isUidValidForRules(int uid) { 17855294a2fc2f401cd248a4bc3f0f9ee1e2854f4e9aJeff Sharkey // allow rules on specific system services, and any apps 17865294a2fc2f401cd248a4bc3f0f9ee1e2854f4e9aJeff Sharkey if (uid == android.os.Process.MEDIA_UID || uid == android.os.Process.DRM_UID 1787f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackborn || UserHandle.isApp(uid)) { 17885294a2fc2f401cd248a4bc3f0f9ee1e2854f4e9aJeff Sharkey return true; 17895294a2fc2f401cd248a4bc3f0f9ee1e2854f4e9aJeff Sharkey } 17905294a2fc2f401cd248a4bc3f0f9ee1e2854f4e9aJeff Sharkey 17915294a2fc2f401cd248a4bc3f0f9ee1e2854f4e9aJeff Sharkey return false; 17925294a2fc2f401cd248a4bc3f0f9ee1e2854f4e9aJeff Sharkey } 17935294a2fc2f401cd248a4bc3f0f9ee1e2854f4e9aJeff Sharkey 179421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private void updateRulesForUidLocked(int uid) { 17955294a2fc2f401cd248a4bc3f0f9ee1e2854f4e9aJeff Sharkey if (!isUidValidForRules(uid)) return; 17965294a2fc2f401cd248a4bc3f0f9ee1e2854f4e9aJeff Sharkey 1797d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey final int uidPolicy = getUidPolicy(uid); 17989599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey final boolean uidForeground = isUidForeground(uid); 1799d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 1800c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey // derive active rules based on policy and active state 1801c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey int uidRules = RULE_ALLOW_ALL; 1802d0c6ccbafdebc73d03cf3cd47f02f9f6c78a69ffJeff Sharkey if (!uidForeground && (uidPolicy & POLICY_REJECT_METERED_BACKGROUND) != 0) { 1803fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey // uid in background, and policy says to block metered data 1804fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey uidRules = RULE_REJECT_METERED; 1805d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey } 18064664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey if (!uidForeground && mRestrictBackground) { 1807b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey // uid in background, and global background disabled 1808b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey uidRules = RULE_REJECT_METERED; 1809b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey } 1810d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey 1811c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey // TODO: only dispatch when rules actually change 1812c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey 1813350083e36b9db6062e165954403ef921ff3dfdadJeff Sharkey if (uidRules == RULE_ALLOW_ALL) { 1814350083e36b9db6062e165954403ef921ff3dfdadJeff Sharkey mUidRules.delete(uid); 1815350083e36b9db6062e165954403ef921ff3dfdadJeff Sharkey } else { 1816350083e36b9db6062e165954403ef921ff3dfdadJeff Sharkey mUidRules.put(uid, uidRules); 1817350083e36b9db6062e165954403ef921ff3dfdadJeff Sharkey } 1818c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey 1819fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkey final boolean rejectMetered = (uidRules & RULE_REJECT_METERED) != 0; 182050fd36d7c38c40b087c8f3e3172478abe0c051d9Ashish Sharma setUidNetworkRules(uid, rejectMetered); 1821497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey 1822c006f1aec15454782c35e028ad64d79a5c161cc1Jeff Sharkey // dispatch changed rule to existing listeners 18234414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey mHandler.obtainMessage(MSG_RULES_CHANGED, uid, uidRules).sendToTarget(); 1824b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey 1825b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey try { 1826b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey // adjust stats accounting based on foreground status 1827b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey mNetworkStats.setUidForeground(uid, uidForeground); 1828b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey } catch (RemoteException e) { 1829b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey // ignored; service lives in system_server 1830b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey } 18314414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey } 18324414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey 18334414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey private Handler.Callback mHandlerCallback = new Handler.Callback() { 1834bfdd680ab44da173a4a39fcd6feccdebb9d1f855Jeff Sharkey @Override 18354414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey public boolean handleMessage(Message msg) { 18364414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey switch (msg.what) { 18374414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey case MSG_RULES_CHANGED: { 18384414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey final int uid = msg.arg1; 18394414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey final int uidRules = msg.arg2; 18404414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey final int length = mListeners.beginBroadcast(); 18414414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey for (int i = 0; i < length; i++) { 18424414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey final INetworkPolicyListener listener = mListeners.getBroadcastItem(i); 18434414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey if (listener != null) { 18444414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey try { 18454414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey listener.onUidRulesChanged(uid, uidRules); 18464414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey } catch (RemoteException e) { 18474414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey } 18484414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey } 18494414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey } 18504414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey mListeners.finishBroadcast(); 18514414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey return true; 18524414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey } 18534414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey case MSG_METERED_IFACES_CHANGED: { 18544414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey final String[] meteredIfaces = (String[]) msg.obj; 18554414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey final int length = mListeners.beginBroadcast(); 18564414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey for (int i = 0; i < length; i++) { 18574414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey final INetworkPolicyListener listener = mListeners.getBroadcastItem(i); 18584414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey if (listener != null) { 18594414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey try { 18604414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey listener.onMeteredIfacesChanged(meteredIfaces); 18614414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey } catch (RemoteException e) { 18624414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey } 18634414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey } 18644414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey } 18654414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey mListeners.finishBroadcast(); 18664414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey return true; 18674414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey } 18686f7af03cf13f76f48e63937e13e4a1c508d100d6Jeff Sharkey case MSG_FOREGROUND_ACTIVITIES_CHANGED: { 18696f7af03cf13f76f48e63937e13e4a1c508d100d6Jeff Sharkey final int pid = msg.arg1; 18706f7af03cf13f76f48e63937e13e4a1c508d100d6Jeff Sharkey final int uid = msg.arg2; 18716f7af03cf13f76f48e63937e13e4a1c508d100d6Jeff Sharkey final boolean foregroundActivities = (Boolean) msg.obj; 18726f7af03cf13f76f48e63937e13e4a1c508d100d6Jeff Sharkey 18736f7af03cf13f76f48e63937e13e4a1c508d100d6Jeff Sharkey synchronized (mRulesLock) { 18746f7af03cf13f76f48e63937e13e4a1c508d100d6Jeff Sharkey // because a uid can have multiple pids running inside, we need to 18756f7af03cf13f76f48e63937e13e4a1c508d100d6Jeff Sharkey // remember all pid states and summarize foreground at uid level. 18766f7af03cf13f76f48e63937e13e4a1c508d100d6Jeff Sharkey 18776f7af03cf13f76f48e63937e13e4a1c508d100d6Jeff Sharkey // record foreground for this specific pid 18786f7af03cf13f76f48e63937e13e4a1c508d100d6Jeff Sharkey SparseBooleanArray pidForeground = mUidPidForeground.get(uid); 18796f7af03cf13f76f48e63937e13e4a1c508d100d6Jeff Sharkey if (pidForeground == null) { 18806f7af03cf13f76f48e63937e13e4a1c508d100d6Jeff Sharkey pidForeground = new SparseBooleanArray(2); 18816f7af03cf13f76f48e63937e13e4a1c508d100d6Jeff Sharkey mUidPidForeground.put(uid, pidForeground); 18826f7af03cf13f76f48e63937e13e4a1c508d100d6Jeff Sharkey } 18836f7af03cf13f76f48e63937e13e4a1c508d100d6Jeff Sharkey pidForeground.put(pid, foregroundActivities); 18846f7af03cf13f76f48e63937e13e4a1c508d100d6Jeff Sharkey computeUidForegroundLocked(uid); 18856f7af03cf13f76f48e63937e13e4a1c508d100d6Jeff Sharkey } 18866f7af03cf13f76f48e63937e13e4a1c508d100d6Jeff Sharkey return true; 18876f7af03cf13f76f48e63937e13e4a1c508d100d6Jeff Sharkey } 18886f7af03cf13f76f48e63937e13e4a1c508d100d6Jeff Sharkey case MSG_PROCESS_DIED: { 18896f7af03cf13f76f48e63937e13e4a1c508d100d6Jeff Sharkey final int pid = msg.arg1; 18906f7af03cf13f76f48e63937e13e4a1c508d100d6Jeff Sharkey final int uid = msg.arg2; 18916f7af03cf13f76f48e63937e13e4a1c508d100d6Jeff Sharkey 18926f7af03cf13f76f48e63937e13e4a1c508d100d6Jeff Sharkey synchronized (mRulesLock) { 18936f7af03cf13f76f48e63937e13e4a1c508d100d6Jeff Sharkey // clear records and recompute, when they exist 18946f7af03cf13f76f48e63937e13e4a1c508d100d6Jeff Sharkey final SparseBooleanArray pidForeground = mUidPidForeground.get(uid); 18956f7af03cf13f76f48e63937e13e4a1c508d100d6Jeff Sharkey if (pidForeground != null) { 18966f7af03cf13f76f48e63937e13e4a1c508d100d6Jeff Sharkey pidForeground.delete(pid); 18976f7af03cf13f76f48e63937e13e4a1c508d100d6Jeff Sharkey computeUidForegroundLocked(uid); 18986f7af03cf13f76f48e63937e13e4a1c508d100d6Jeff Sharkey } 18996f7af03cf13f76f48e63937e13e4a1c508d100d6Jeff Sharkey } 19006f7af03cf13f76f48e63937e13e4a1c508d100d6Jeff Sharkey return true; 19016f7af03cf13f76f48e63937e13e4a1c508d100d6Jeff Sharkey } 19027e25b0ea8891ffc0ac472d61f21610a9ac4e270aJeff Sharkey case MSG_LIMIT_REACHED: { 19037e25b0ea8891ffc0ac472d61f21610a9ac4e270aJeff Sharkey final String iface = (String) msg.obj; 19047e25b0ea8891ffc0ac472d61f21610a9ac4e270aJeff Sharkey 1905684c54a2eb860062f1960f4eba6bc71aa1cfa71dJeff Sharkey maybeRefreshTrustedTime(); 19067e25b0ea8891ffc0ac472d61f21610a9ac4e270aJeff Sharkey synchronized (mRulesLock) { 19077e25b0ea8891ffc0ac472d61f21610a9ac4e270aJeff Sharkey if (mMeteredIfaces.contains(iface)) { 19087e25b0ea8891ffc0ac472d61f21610a9ac4e270aJeff Sharkey try { 19097e25b0ea8891ffc0ac472d61f21610a9ac4e270aJeff Sharkey // force stats update to make sure we have 19107e25b0ea8891ffc0ac472d61f21610a9ac4e270aJeff Sharkey // numbers that caused alert to trigger. 19117e25b0ea8891ffc0ac472d61f21610a9ac4e270aJeff Sharkey mNetworkStats.forceUpdate(); 19127e25b0ea8891ffc0ac472d61f21610a9ac4e270aJeff Sharkey } catch (RemoteException e) { 19137e25b0ea8891ffc0ac472d61f21610a9ac4e270aJeff Sharkey // ignored; service lives in system_server 19147e25b0ea8891ffc0ac472d61f21610a9ac4e270aJeff Sharkey } 19157e25b0ea8891ffc0ac472d61f21610a9ac4e270aJeff Sharkey 19167e25b0ea8891ffc0ac472d61f21610a9ac4e270aJeff Sharkey updateNetworkEnabledLocked(); 19177e25b0ea8891ffc0ac472d61f21610a9ac4e270aJeff Sharkey updateNotificationsLocked(); 19187e25b0ea8891ffc0ac472d61f21610a9ac4e270aJeff Sharkey } 19197e25b0ea8891ffc0ac472d61f21610a9ac4e270aJeff Sharkey } 19207e25b0ea8891ffc0ac472d61f21610a9ac4e270aJeff Sharkey return true; 19217e25b0ea8891ffc0ac472d61f21610a9ac4e270aJeff Sharkey } 19221f8ea2dcd1ed3cde4b84fbb27b5a55b3fea7ff2aJeff Sharkey case MSG_RESTRICT_BACKGROUND_CHANGED: { 19231f8ea2dcd1ed3cde4b84fbb27b5a55b3fea7ff2aJeff Sharkey final boolean restrictBackground = msg.arg1 != 0; 19241f8ea2dcd1ed3cde4b84fbb27b5a55b3fea7ff2aJeff Sharkey final int length = mListeners.beginBroadcast(); 19251f8ea2dcd1ed3cde4b84fbb27b5a55b3fea7ff2aJeff Sharkey for (int i = 0; i < length; i++) { 19261f8ea2dcd1ed3cde4b84fbb27b5a55b3fea7ff2aJeff Sharkey final INetworkPolicyListener listener = mListeners.getBroadcastItem(i); 19271f8ea2dcd1ed3cde4b84fbb27b5a55b3fea7ff2aJeff Sharkey if (listener != null) { 19281f8ea2dcd1ed3cde4b84fbb27b5a55b3fea7ff2aJeff Sharkey try { 19291f8ea2dcd1ed3cde4b84fbb27b5a55b3fea7ff2aJeff Sharkey listener.onRestrictBackgroundChanged(restrictBackground); 19301f8ea2dcd1ed3cde4b84fbb27b5a55b3fea7ff2aJeff Sharkey } catch (RemoteException e) { 19311f8ea2dcd1ed3cde4b84fbb27b5a55b3fea7ff2aJeff Sharkey } 19321f8ea2dcd1ed3cde4b84fbb27b5a55b3fea7ff2aJeff Sharkey } 19331f8ea2dcd1ed3cde4b84fbb27b5a55b3fea7ff2aJeff Sharkey } 19341f8ea2dcd1ed3cde4b84fbb27b5a55b3fea7ff2aJeff Sharkey mListeners.finishBroadcast(); 1935e19f39b79c831aea4d51a3309025acdf69d1e609Jeff Sharkey return true; 1936e19f39b79c831aea4d51a3309025acdf69d1e609Jeff Sharkey } 1937e19f39b79c831aea4d51a3309025acdf69d1e609Jeff Sharkey case MSG_ADVISE_PERSIST_THRESHOLD: { 1938e19f39b79c831aea4d51a3309025acdf69d1e609Jeff Sharkey final long lowestRule = (Long) msg.obj; 1939e19f39b79c831aea4d51a3309025acdf69d1e609Jeff Sharkey try { 1940e19f39b79c831aea4d51a3309025acdf69d1e609Jeff Sharkey // make sure stats are recorded frequently enough; we aim 1941e19f39b79c831aea4d51a3309025acdf69d1e609Jeff Sharkey // for 2MB threshold for 2GB/month rules. 1942e19f39b79c831aea4d51a3309025acdf69d1e609Jeff Sharkey final long persistThreshold = lowestRule / 1000; 1943e19f39b79c831aea4d51a3309025acdf69d1e609Jeff Sharkey mNetworkStats.advisePersistThreshold(persistThreshold); 1944e19f39b79c831aea4d51a3309025acdf69d1e609Jeff Sharkey } catch (RemoteException e) { 1945e19f39b79c831aea4d51a3309025acdf69d1e609Jeff Sharkey // ignored; service lives in system_server 1946e19f39b79c831aea4d51a3309025acdf69d1e609Jeff Sharkey } 1947e19f39b79c831aea4d51a3309025acdf69d1e609Jeff Sharkey return true; 19481f8ea2dcd1ed3cde4b84fbb27b5a55b3fea7ff2aJeff Sharkey } 19490abe556d28f5f5d395559cc6567b05939d1b2640Jeff Sharkey case MSG_SCREEN_ON_CHANGED: { 19500abe556d28f5f5d395559cc6567b05939d1b2640Jeff Sharkey updateScreenOn(); 19510abe556d28f5f5d395559cc6567b05939d1b2640Jeff Sharkey return true; 19520abe556d28f5f5d395559cc6567b05939d1b2640Jeff Sharkey } 19534414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey default: { 19544414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey return false; 1955af11d4859582a9736aa204562f0beac5a7d60934Jeff Sharkey } 1956af11d4859582a9736aa204562f0beac5a7d60934Jeff Sharkey } 1957af11d4859582a9736aa204562f0beac5a7d60934Jeff Sharkey } 19584414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey }; 195922c055e6424e0e9579711545d8f4800c0f796db8Jeff Sharkey 196041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey private void setInterfaceQuota(String iface, long quotaBytes) { 1961b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey try { 196241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey mNetworkManager.setInterfaceQuota(iface, quotaBytes); 1963b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey } catch (IllegalStateException e) { 1964b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey Log.wtf(TAG, "problem setting interface quota", e); 1965b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey } catch (RemoteException e) { 1966b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey // ignored; service lives in system_server 1967b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey } 1968b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey } 1969b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey 1970b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey private void removeInterfaceQuota(String iface) { 1971b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey try { 197241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey mNetworkManager.removeInterfaceQuota(iface); 1973b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey } catch (IllegalStateException e) { 1974b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey Log.wtf(TAG, "problem removing interface quota", e); 1975b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey } catch (RemoteException e) { 1976b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey // ignored; service lives in system_server 197741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey } 197841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey } 197941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey 1980b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey private void setUidNetworkRules(int uid, boolean rejectOnQuotaInterfaces) { 1981b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey try { 198241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey mNetworkManager.setUidNetworkRules(uid, rejectOnQuotaInterfaces); 1983b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey } catch (IllegalStateException e) { 1984b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey Log.wtf(TAG, "problem setting uid rules", e); 1985b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey } catch (RemoteException e) { 1986b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey // ignored; service lives in system_server 1987b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey } 1988b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey } 1989b3f19ca36c8c1301893c621d8f2150e06210722cJeff Sharkey 19908e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey /** 19913f3115b27733a822104385284b1ec1f39d91f839Jeff Sharkey * Control {@link IConnectivityManager#setPolicyDataEnable(int, boolean)}. 19928e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey */ 19938e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey private void setPolicyDataEnable(int networkType, boolean enabled) { 19943f3115b27733a822104385284b1ec1f39d91f839Jeff Sharkey try { 19953f3115b27733a822104385284b1ec1f39d91f839Jeff Sharkey mConnManager.setPolicyDataEnable(networkType, enabled); 19963f3115b27733a822104385284b1ec1f39d91f839Jeff Sharkey } catch (RemoteException e) { 19973f3115b27733a822104385284b1ec1f39d91f839Jeff Sharkey // ignored; service lives in system_server 19988e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey } 19998e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey } 20008e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey 20018e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey private long getTotalBytes(NetworkTemplate template, long start, long end) { 20028e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey try { 2003b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey return mNetworkStats.getNetworkTotalBytes(template, start, end); 200463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey } catch (RuntimeException e) { 200563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey Slog.w(TAG, "problem reading network stats: " + e); 200663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey return 0; 20078e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey } catch (RemoteException e) { 2008b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey // ignored; service lives in system_server 2009b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey return 0; 20108e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey } 20118e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey } 20128e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey 20138c1dc72b1402d55dae388a294476565b2473a87aJeff Sharkey private boolean isBandwidthControlEnabled() { 20148c1dc72b1402d55dae388a294476565b2473a87aJeff Sharkey final long token = Binder.clearCallingIdentity(); 20158c1dc72b1402d55dae388a294476565b2473a87aJeff Sharkey try { 20168c1dc72b1402d55dae388a294476565b2473a87aJeff Sharkey return mNetworkManager.isBandwidthControlEnabled(); 20178c1dc72b1402d55dae388a294476565b2473a87aJeff Sharkey } catch (RemoteException e) { 20188c1dc72b1402d55dae388a294476565b2473a87aJeff Sharkey // ignored; service lives in system_server 20198c1dc72b1402d55dae388a294476565b2473a87aJeff Sharkey return false; 20208c1dc72b1402d55dae388a294476565b2473a87aJeff Sharkey } finally { 20218c1dc72b1402d55dae388a294476565b2473a87aJeff Sharkey Binder.restoreCallingIdentity(token); 20228c1dc72b1402d55dae388a294476565b2473a87aJeff Sharkey } 20238c1dc72b1402d55dae388a294476565b2473a87aJeff Sharkey } 20248c1dc72b1402d55dae388a294476565b2473a87aJeff Sharkey 2025684c54a2eb860062f1960f4eba6bc71aa1cfa71dJeff Sharkey /** 2026684c54a2eb860062f1960f4eba6bc71aa1cfa71dJeff Sharkey * Try refreshing {@link #mTime} when stale. 2027684c54a2eb860062f1960f4eba6bc71aa1cfa71dJeff Sharkey */ 2028684c54a2eb860062f1960f4eba6bc71aa1cfa71dJeff Sharkey private void maybeRefreshTrustedTime() { 2029684c54a2eb860062f1960f4eba6bc71aa1cfa71dJeff Sharkey if (mTime.getCacheAge() > TIME_CACHE_MAX_AGE) { 20308e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey mTime.forceRefresh(); 20318e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey } 2032684c54a2eb860062f1960f4eba6bc71aa1cfa71dJeff Sharkey } 20338e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey 2034684c54a2eb860062f1960f4eba6bc71aa1cfa71dJeff Sharkey private long currentTimeMillis() { 20358e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey return mTime.hasCache() ? mTime.currentTimeMillis() : System.currentTimeMillis(); 20368e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey } 20378e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey 20383a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey private static Intent buildAllowBackgroundDataIntent() { 20393a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey return new Intent(ACTION_ALLOW_BACKGROUND); 20403a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey } 20413a844fcf5a0e70a19c38dc500306b9ebe4e1413bJeff Sharkey 20420e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey private static Intent buildSnoozeWarningIntent(NetworkTemplate template) { 20430e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey final Intent intent = new Intent(ACTION_SNOOZE_WARNING); 20440e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey intent.putExtra(EXTRA_NETWORK_TEMPLATE, template); 20450e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey return intent; 20460e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey } 20470e2e5f8b564bebd5798c9fa387fbff96429ab5d2Jeff Sharkey 204841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey private static Intent buildNetworkOverLimitIntent(NetworkTemplate template) { 204941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey final Intent intent = new Intent(); 205041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey intent.setComponent(new ComponentName( 205141ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey "com.android.systemui", "com.android.systemui.net.NetworkOverLimitActivity")); 205241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 205341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey intent.putExtra(EXTRA_NETWORK_TEMPLATE, template); 205441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey return intent; 205541ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey } 205641ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey 205741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey private static Intent buildViewDataUsageIntent(NetworkTemplate template) { 205841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey final Intent intent = new Intent(); 205941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey intent.setComponent(new ComponentName( 206041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey "com.android.settings", "com.android.settings.Settings$DataUsageSummaryActivity")); 206141ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 206241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey intent.putExtra(EXTRA_NETWORK_TEMPLATE, template); 206341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey return intent; 206441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey } 206541ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey 2066163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey // @VisibleForTesting 2067163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey public void addIdleHandler(IdleHandler handler) { 2068163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey mHandler.getLooper().getQueue().addIdleHandler(handler); 2069163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey } 2070163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey 20711b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey private static void collectKeys(SparseIntArray source, SparseBooleanArray target) { 20721b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey final int size = source.size(); 20731b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey for (int i = 0; i < size; i++) { 20741b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey target.put(source.keyAt(i), true); 20751b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } 20761b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } 20771b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey 20781b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey private static void collectKeys(SparseBooleanArray source, SparseBooleanArray target) { 20791b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey final int size = source.size(); 20801b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey for (int i = 0; i < size; i++) { 20811b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey target.put(source.keyAt(i), true); 20821b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } 20831b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } 20841b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey 20851b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey private static void dumpSparseBooleanArray(PrintWriter fout, SparseBooleanArray value) { 20861b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey fout.print("["); 20871b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey final int size = value.size(); 20881b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey for (int i = 0; i < size; i++) { 20891b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey fout.print(value.keyAt(i) + "=" + value.valueAt(i)); 20901b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey if (i < size - 1) fout.print(","); 20911b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } 20921b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey fout.print("]"); 20931b861278a2051f53ce7955fb7992fa536dc975d9Jeff Sharkey } 209421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 20954664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey public static class XmlUtils { 20964664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey public static int readIntAttribute(XmlPullParser in, String name) throws IOException { 20974664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey final String value = in.getAttributeValue(null, name); 20984664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey try { 20994664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey return Integer.parseInt(value); 21004664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey } catch (NumberFormatException e) { 21014664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey throw new ProtocolException("problem parsing " + name + "=" + value + " as int"); 21024664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey } 210321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 210421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 21054664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey public static void writeIntAttribute(XmlSerializer out, String name, int value) 21064664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey throws IOException { 21074664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey out.attribute(null, name, Integer.toString(value)); 210821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 210921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 21104664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey public static long readLongAttribute(XmlPullParser in, String name) throws IOException { 21114664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey final String value = in.getAttributeValue(null, name); 21124664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey try { 21134664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey return Long.parseLong(value); 21144664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey } catch (NumberFormatException e) { 21154664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey throw new ProtocolException("problem parsing " + name + "=" + value + " as long"); 21164664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey } 21174664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey } 211821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 21194664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey public static void writeLongAttribute(XmlSerializer out, String name, long value) 21204664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey throws IOException { 21214664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey out.attribute(null, name, Long.toString(value)); 21224664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey } 212321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 21244664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey public static boolean readBooleanAttribute(XmlPullParser in, String name) { 21254664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey final String value = in.getAttributeValue(null, name); 21264664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey return Boolean.parseBoolean(value); 21274664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey } 21284664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey 21294664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey public static void writeBooleanAttribute(XmlSerializer out, String name, boolean value) 21304664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey throws IOException { 21314664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey out.attribute(null, name, Boolean.toString(value)); 21324664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey } 21334664500de0c1b270bce4991a400ab439ff2ef77bJeff Sharkey } 2134d5cdd597b895a48ffa9a8e39f8a2504cd9b905c4Jeff Sharkey} 2135