1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.net; 18 19 import static android.Manifest.permission.ACCESS_NETWORK_STATE; 20 import static android.Manifest.permission.CONNECTIVITY_INTERNAL; 21 import static android.Manifest.permission.DUMP; 22 import static android.Manifest.permission.MANAGE_APP_TOKENS; 23 import static android.Manifest.permission.MANAGE_NETWORK_POLICY; 24 import static android.Manifest.permission.READ_NETWORK_USAGE_HISTORY; 25 import static android.Manifest.permission.READ_PHONE_STATE; 26 import static android.content.Intent.ACTION_PACKAGE_ADDED; 27 import static android.content.Intent.ACTION_UID_REMOVED; 28 import static android.content.Intent.EXTRA_UID; 29 import static android.net.ConnectivityManager.CONNECTIVITY_ACTION_IMMEDIATE; 30 import static android.net.ConnectivityManager.TYPE_ETHERNET; 31 import static android.net.ConnectivityManager.TYPE_MOBILE; 32 import static android.net.ConnectivityManager.TYPE_WIFI; 33 import static android.net.ConnectivityManager.TYPE_WIMAX; 34 import static android.net.NetworkPolicy.LIMIT_DISABLED; 35 import static android.net.NetworkPolicy.SNOOZE_NEVER; 36 import static android.net.NetworkPolicy.WARNING_DISABLED; 37 import static android.net.NetworkPolicyManager.EXTRA_NETWORK_TEMPLATE; 38 import static android.net.NetworkPolicyManager.POLICY_NONE; 39 import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND; 40 import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL; 41 import static android.net.NetworkPolicyManager.RULE_REJECT_METERED; 42 import static android.net.NetworkPolicyManager.computeLastCycleBoundary; 43 import static android.net.NetworkPolicyManager.dumpPolicy; 44 import static android.net.NetworkPolicyManager.dumpRules; 45 import static android.net.NetworkPolicyManager.isUidValidForPolicy; 46 import static android.net.NetworkTemplate.MATCH_ETHERNET; 47 import static android.net.NetworkTemplate.MATCH_MOBILE_3G_LOWER; 48 import static android.net.NetworkTemplate.MATCH_MOBILE_4G; 49 import static android.net.NetworkTemplate.MATCH_MOBILE_ALL; 50 import static android.net.NetworkTemplate.MATCH_WIFI; 51 import static android.net.NetworkTemplate.buildTemplateMobileAll; 52 import static android.text.format.DateUtils.DAY_IN_MILLIS; 53 import static com.android.internal.util.Preconditions.checkNotNull; 54 import static com.android.server.NetworkManagementService.LIMIT_GLOBAL_ALERT; 55 import static com.android.server.net.NetworkPolicyManagerService.XmlUtils.readBooleanAttribute; 56 import static com.android.server.net.NetworkPolicyManagerService.XmlUtils.readIntAttribute; 57 import static com.android.server.net.NetworkPolicyManagerService.XmlUtils.readLongAttribute; 58 import static com.android.server.net.NetworkPolicyManagerService.XmlUtils.writeBooleanAttribute; 59 import static com.android.server.net.NetworkPolicyManagerService.XmlUtils.writeIntAttribute; 60 import static com.android.server.net.NetworkPolicyManagerService.XmlUtils.writeLongAttribute; 61 import static com.android.server.net.NetworkStatsService.ACTION_NETWORK_STATS_UPDATED; 62 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 63 import static org.xmlpull.v1.XmlPullParser.START_TAG; 64 65 import android.app.IActivityManager; 66 import android.app.INotificationManager; 67 import android.app.IProcessObserver; 68 import android.app.Notification; 69 import android.app.PendingIntent; 70 import android.content.BroadcastReceiver; 71 import android.content.ComponentName; 72 import android.content.Context; 73 import android.content.Intent; 74 import android.content.IntentFilter; 75 import android.content.pm.ApplicationInfo; 76 import android.content.pm.PackageManager; 77 import android.content.res.Resources; 78 import android.net.ConnectivityManager; 79 import android.net.IConnectivityManager; 80 import android.net.INetworkManagementEventObserver; 81 import android.net.INetworkPolicyListener; 82 import android.net.INetworkPolicyManager; 83 import android.net.INetworkStatsService; 84 import android.net.NetworkIdentity; 85 import android.net.NetworkPolicy; 86 import android.net.NetworkQuotaInfo; 87 import android.net.NetworkState; 88 import android.net.NetworkTemplate; 89 import android.os.Binder; 90 import android.os.Environment; 91 import android.os.Handler; 92 import android.os.HandlerThread; 93 import android.os.INetworkManagementService; 94 import android.os.IPowerManager; 95 import android.os.Message; 96 import android.os.RemoteCallbackList; 97 import android.os.RemoteException; 98 import android.provider.Settings; 99 import android.telephony.TelephonyManager; 100 import android.text.format.Formatter; 101 import android.text.format.Time; 102 import android.util.Log; 103 import android.util.NtpTrustedTime; 104 import android.util.Slog; 105 import android.util.SparseArray; 106 import android.util.SparseBooleanArray; 107 import android.util.SparseIntArray; 108 import android.util.TrustedTime; 109 import android.util.Xml; 110 111 import com.android.internal.R; 112 import com.android.internal.os.AtomicFile; 113 import com.android.internal.util.FastXmlSerializer; 114 import com.android.internal.util.Objects; 115 import com.google.android.collect.Lists; 116 import com.google.android.collect.Maps; 117 import com.google.android.collect.Sets; 118 119 import org.xmlpull.v1.XmlPullParser; 120 import org.xmlpull.v1.XmlPullParserException; 121 import org.xmlpull.v1.XmlSerializer; 122 123 import java.io.File; 124 import java.io.FileDescriptor; 125 import java.io.FileInputStream; 126 import java.io.FileNotFoundException; 127 import java.io.FileOutputStream; 128 import java.io.IOException; 129 import java.io.PrintWriter; 130 import java.net.ProtocolException; 131 import java.util.ArrayList; 132 import java.util.Arrays; 133 import java.util.HashMap; 134 import java.util.HashSet; 135 import java.util.List; 136 import java.util.Map; 137 138 import libcore.io.IoUtils; 139 140 /** 141 * Service that maintains low-level network policy rules, using 142 * {@link NetworkStatsService} statistics to drive those rules. 143 * <p> 144 * Derives active rules by combining a given policy with other system status, 145 * and delivers to listeners, such as {@link ConnectivityManager}, for 146 * enforcement. 147 */ 148 public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { 149 private static final String TAG = "NetworkPolicy"; 150 private static final boolean LOGD = true; 151 private static final boolean LOGV = false; 152 153 private static final int VERSION_INIT = 1; 154 private static final int VERSION_ADDED_SNOOZE = 2; 155 private static final int VERSION_ADDED_RESTRICT_BACKGROUND = 3; 156 157 private static final long KB_IN_BYTES = 1024; 158 private static final long MB_IN_BYTES = KB_IN_BYTES * 1024; 159 private static final long GB_IN_BYTES = MB_IN_BYTES * 1024; 160 161 // @VisibleForTesting 162 public static final int TYPE_WARNING = 0x1; 163 public static final int TYPE_LIMIT = 0x2; 164 public static final int TYPE_LIMIT_SNOOZED = 0x3; 165 166 private static final String TAG_POLICY_LIST = "policy-list"; 167 private static final String TAG_NETWORK_POLICY = "network-policy"; 168 private static final String TAG_UID_POLICY = "uid-policy"; 169 170 private static final String ATTR_VERSION = "version"; 171 private static final String ATTR_RESTRICT_BACKGROUND = "restrictBackground"; 172 private static final String ATTR_NETWORK_TEMPLATE = "networkTemplate"; 173 private static final String ATTR_SUBSCRIBER_ID = "subscriberId"; 174 private static final String ATTR_CYCLE_DAY = "cycleDay"; 175 private static final String ATTR_WARNING_BYTES = "warningBytes"; 176 private static final String ATTR_LIMIT_BYTES = "limitBytes"; 177 private static final String ATTR_LAST_SNOOZE = "lastSnooze"; 178 private static final String ATTR_UID = "uid"; 179 private static final String ATTR_POLICY = "policy"; 180 181 private static final String TAG_ALLOW_BACKGROUND = TAG + ":allowBackground"; 182 183 // @VisibleForTesting 184 public static final String ACTION_ALLOW_BACKGROUND = 185 "com.android.server.action.ACTION_ALLOW_BACKGROUND"; 186 187 private static final long TIME_CACHE_MAX_AGE = DAY_IN_MILLIS; 188 189 private static final int MSG_RULES_CHANGED = 1; 190 private static final int MSG_METERED_IFACES_CHANGED = 2; 191 private static final int MSG_FOREGROUND_ACTIVITIES_CHANGED = 3; 192 private static final int MSG_PROCESS_DIED = 4; 193 194 private final Context mContext; 195 private final IActivityManager mActivityManager; 196 private final IPowerManager mPowerManager; 197 private final INetworkStatsService mNetworkStats; 198 private final INetworkManagementService mNetworkManager; 199 private final TrustedTime mTime; 200 201 private IConnectivityManager mConnManager; 202 private INotificationManager mNotifManager; 203 204 private final Object mRulesLock = new Object(); 205 206 private volatile boolean mScreenOn; 207 private volatile boolean mRestrictBackground; 208 209 private final boolean mSuppressDefaultPolicy; 210 211 /** Defined network policies. */ 212 private HashMap<NetworkTemplate, NetworkPolicy> mNetworkPolicy = Maps.newHashMap(); 213 /** Currently active network rules for ifaces. */ 214 private HashMap<NetworkPolicy, String[]> mNetworkRules = Maps.newHashMap(); 215 216 /** Defined UID policies. */ 217 private SparseIntArray mUidPolicy = new SparseIntArray(); 218 /** Currently derived rules for each UID. */ 219 private SparseIntArray mUidRules = new SparseIntArray(); 220 221 /** Set of ifaces that are metered. */ 222 private HashSet<String> mMeteredIfaces = Sets.newHashSet(); 223 /** Set of over-limit templates that have been notified. */ 224 private HashSet<NetworkTemplate> mOverLimitNotified = Sets.newHashSet(); 225 226 /** Set of currently active {@link Notification} tags. */ 227 private HashSet<String> mActiveNotifs = Sets.newHashSet(); 228 /** Current values from {@link #setPolicyDataEnable(int, boolean)}. */ 229 private SparseBooleanArray mActiveNetworkEnabled = new SparseBooleanArray(); 230 231 /** Foreground at both UID and PID granularity. */ 232 private SparseBooleanArray mUidForeground = new SparseBooleanArray(); 233 private SparseArray<SparseBooleanArray> mUidPidForeground = new SparseArray< 234 SparseBooleanArray>(); 235 236 private final RemoteCallbackList<INetworkPolicyListener> mListeners = new RemoteCallbackList< 237 INetworkPolicyListener>(); 238 239 private final HandlerThread mHandlerThread; 240 private final Handler mHandler; 241 242 private final AtomicFile mPolicyFile; 243 244 // TODO: keep whitelist of system-critical services that should never have 245 // rules enforced, such as system, phone, and radio UIDs. 246 247 // TODO: migrate notifications to SystemUI 248 249 public NetworkPolicyManagerService(Context context, IActivityManager activityManager, 250 IPowerManager powerManager, INetworkStatsService networkStats, 251 INetworkManagementService networkManagement) { 252 this(context, activityManager, powerManager, networkStats, networkManagement, 253 NtpTrustedTime.getInstance(context), getSystemDir(), false); 254 } 255 256 private static File getSystemDir() { 257 return new File(Environment.getDataDirectory(), "system"); 258 } 259 260 public NetworkPolicyManagerService(Context context, IActivityManager activityManager, 261 IPowerManager powerManager, INetworkStatsService networkStats, 262 INetworkManagementService networkManagement, TrustedTime time, File systemDir, 263 boolean suppressDefaultPolicy) { 264 mContext = checkNotNull(context, "missing context"); 265 mActivityManager = checkNotNull(activityManager, "missing activityManager"); 266 mPowerManager = checkNotNull(powerManager, "missing powerManager"); 267 mNetworkStats = checkNotNull(networkStats, "missing networkStats"); 268 mNetworkManager = checkNotNull(networkManagement, "missing networkManagement"); 269 mTime = checkNotNull(time, "missing TrustedTime"); 270 271 mHandlerThread = new HandlerThread(TAG); 272 mHandlerThread.start(); 273 mHandler = new Handler(mHandlerThread.getLooper(), mHandlerCallback); 274 275 mSuppressDefaultPolicy = suppressDefaultPolicy; 276 277 mPolicyFile = new AtomicFile(new File(systemDir, "netpolicy.xml")); 278 } 279 280 public void bindConnectivityManager(IConnectivityManager connManager) { 281 mConnManager = checkNotNull(connManager, "missing IConnectivityManager"); 282 } 283 284 public void bindNotificationManager(INotificationManager notifManager) { 285 mNotifManager = checkNotNull(notifManager, "missing INotificationManager"); 286 } 287 288 public void systemReady() { 289 synchronized (mRulesLock) { 290 // read policy from disk 291 readPolicyLocked(); 292 293 if (mRestrictBackground) { 294 updateRulesForRestrictBackgroundLocked(); 295 updateNotificationsLocked(); 296 } 297 } 298 299 updateScreenOn(); 300 301 try { 302 mActivityManager.registerProcessObserver(mProcessObserver); 303 mNetworkManager.registerObserver(mAlertObserver); 304 } catch (RemoteException e) { 305 // ignored; both services live in system_server 306 } 307 308 // TODO: traverse existing processes to know foreground state, or have 309 // activitymanager dispatch current state when new observer attached. 310 311 final IntentFilter screenFilter = new IntentFilter(); 312 screenFilter.addAction(Intent.ACTION_SCREEN_ON); 313 screenFilter.addAction(Intent.ACTION_SCREEN_OFF); 314 mContext.registerReceiver(mScreenReceiver, screenFilter, null, mHandler); 315 316 // watch for network interfaces to be claimed 317 final IntentFilter connFilter = new IntentFilter(CONNECTIVITY_ACTION_IMMEDIATE); 318 mContext.registerReceiver(mConnReceiver, connFilter, CONNECTIVITY_INTERNAL, mHandler); 319 320 // listen for package/uid changes to update policy 321 final IntentFilter packageFilter = new IntentFilter(); 322 packageFilter.addAction(ACTION_PACKAGE_ADDED); 323 packageFilter.addAction(ACTION_UID_REMOVED); 324 mContext.registerReceiver(mPackageReceiver, packageFilter, null, mHandler); 325 326 // listen for stats update events 327 final IntentFilter statsFilter = new IntentFilter(ACTION_NETWORK_STATS_UPDATED); 328 mContext.registerReceiver( 329 mStatsReceiver, statsFilter, READ_NETWORK_USAGE_HISTORY, mHandler); 330 331 // listen for restrict background changes from notifications 332 final IntentFilter allowFilter = new IntentFilter(ACTION_ALLOW_BACKGROUND); 333 mContext.registerReceiver(mAllowReceiver, allowFilter, MANAGE_NETWORK_POLICY, mHandler); 334 335 } 336 337 private IProcessObserver mProcessObserver = new IProcessObserver.Stub() { 338 @Override 339 public void onForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities) { 340 mHandler.obtainMessage(MSG_FOREGROUND_ACTIVITIES_CHANGED, 341 pid, uid, foregroundActivities).sendToTarget(); 342 } 343 344 @Override 345 public void onProcessDied(int pid, int uid) { 346 mHandler.obtainMessage(MSG_PROCESS_DIED, pid, uid).sendToTarget(); 347 } 348 }; 349 350 private BroadcastReceiver mScreenReceiver = new BroadcastReceiver() { 351 @Override 352 public void onReceive(Context context, Intent intent) { 353 synchronized (mRulesLock) { 354 // screen-related broadcasts are protected by system, no need 355 // for permissions check. 356 updateScreenOn(); 357 } 358 } 359 }; 360 361 private BroadcastReceiver mPackageReceiver = new BroadcastReceiver() { 362 @Override 363 public void onReceive(Context context, Intent intent) { 364 // on background handler thread, and PACKAGE_ADDED and UID_REMOVED 365 // are protected broadcasts. 366 367 final String action = intent.getAction(); 368 final int uid = intent.getIntExtra(EXTRA_UID, 0); 369 synchronized (mRulesLock) { 370 if (ACTION_PACKAGE_ADDED.equals(action)) { 371 // update rules for UID, since it might be subject to 372 // global background data policy. 373 if (LOGV) Slog.v(TAG, "ACTION_PACKAGE_ADDED for uid=" + uid); 374 updateRulesForUidLocked(uid); 375 376 } else if (ACTION_UID_REMOVED.equals(action)) { 377 // remove any policy and update rules to clean up. 378 if (LOGV) Slog.v(TAG, "ACTION_UID_REMOVED for uid=" + uid); 379 mUidPolicy.delete(uid); 380 updateRulesForUidLocked(uid); 381 writePolicyLocked(); 382 } 383 } 384 } 385 }; 386 387 /** 388 * Receiver that watches for {@link INetworkStatsService} updates, which we 389 * use to check against {@link NetworkPolicy#warningBytes}. 390 */ 391 private BroadcastReceiver mStatsReceiver = new BroadcastReceiver() { 392 @Override 393 public void onReceive(Context context, Intent intent) { 394 // on background handler thread, and verified 395 // READ_NETWORK_USAGE_HISTORY permission above. 396 397 synchronized (mRulesLock) { 398 updateNetworkEnabledLocked(); 399 updateNotificationsLocked(); 400 } 401 } 402 }; 403 404 /** 405 * Receiver that watches for {@link Notification} control of 406 * {@link #mRestrictBackground}. 407 */ 408 private BroadcastReceiver mAllowReceiver = new BroadcastReceiver() { 409 @Override 410 public void onReceive(Context context, Intent intent) { 411 // on background handler thread, and verified MANAGE_NETWORK_POLICY 412 // permission above. 413 414 setRestrictBackground(false); 415 } 416 }; 417 418 /** 419 * Observer that watches for {@link INetworkManagementService} alerts. 420 */ 421 private INetworkManagementEventObserver mAlertObserver = new NetworkAlertObserver() { 422 @Override 423 public void limitReached(String limitName, String iface) { 424 // only someone like NMS should be calling us 425 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 426 427 synchronized (mRulesLock) { 428 if (mMeteredIfaces.contains(iface) && !LIMIT_GLOBAL_ALERT.equals(limitName)) { 429 try { 430 // force stats update to make sure we have numbers that 431 // caused alert to trigger. 432 mNetworkStats.forceUpdate(); 433 } catch (RemoteException e) { 434 // ignored; service lives in system_server 435 } 436 437 updateNetworkEnabledLocked(); 438 updateNotificationsLocked(); 439 } 440 } 441 } 442 }; 443 444 /** 445 * Check {@link NetworkPolicy} against current {@link INetworkStatsService} 446 * to show visible notifications as needed. 447 */ 448 private void updateNotificationsLocked() { 449 if (LOGV) Slog.v(TAG, "updateNotificationsLocked()"); 450 451 // keep track of previously active notifications 452 final HashSet<String> beforeNotifs = Sets.newHashSet(); 453 beforeNotifs.addAll(mActiveNotifs); 454 mActiveNotifs.clear(); 455 456 // TODO: when switching to kernel notifications, compute next future 457 // cycle boundary to recompute notifications. 458 459 // examine stats for each active policy 460 final long currentTime = currentTimeMillis(true); 461 for (NetworkPolicy policy : mNetworkPolicy.values()) { 462 // ignore policies that aren't relevant to user 463 if (!isTemplateRelevant(policy.template)) continue; 464 465 final long start = computeLastCycleBoundary(currentTime, policy); 466 final long end = currentTime; 467 final long totalBytes = getTotalBytes(policy.template, start, end); 468 469 if (policy.isOverLimit(totalBytes)) { 470 if (policy.lastSnooze >= start) { 471 enqueueNotification(policy, TYPE_LIMIT_SNOOZED, totalBytes); 472 } else { 473 enqueueNotification(policy, TYPE_LIMIT, totalBytes); 474 notifyOverLimitLocked(policy.template); 475 } 476 477 } else { 478 notifyUnderLimitLocked(policy.template); 479 480 if (policy.warningBytes != WARNING_DISABLED && totalBytes >= policy.warningBytes) { 481 enqueueNotification(policy, TYPE_WARNING, totalBytes); 482 } 483 } 484 } 485 486 // ongoing notification when restricting background data 487 if (mRestrictBackground) { 488 enqueueRestrictedNotification(TAG_ALLOW_BACKGROUND); 489 } 490 491 // cancel stale notifications that we didn't renew above 492 for (String tag : beforeNotifs) { 493 if (!mActiveNotifs.contains(tag)) { 494 cancelNotification(tag); 495 } 496 } 497 } 498 499 /** 500 * Test if given {@link NetworkTemplate} is relevant to user based on 501 * current device state, such as when {@link #getActiveSubscriberId()} 502 * matches. This is regardless of data connection status. 503 */ 504 private boolean isTemplateRelevant(NetworkTemplate template) { 505 switch (template.getMatchRule()) { 506 case MATCH_MOBILE_3G_LOWER: 507 case MATCH_MOBILE_4G: 508 case MATCH_MOBILE_ALL: 509 // mobile templates are relevant when subscriberid is active 510 return Objects.equal(getActiveSubscriberId(), template.getSubscriberId()); 511 } 512 return true; 513 } 514 515 /** 516 * Notify that given {@link NetworkTemplate} is over 517 * {@link NetworkPolicy#limitBytes}, potentially showing dialog to user. 518 */ 519 private void notifyOverLimitLocked(NetworkTemplate template) { 520 if (!mOverLimitNotified.contains(template)) { 521 mContext.startActivity(buildNetworkOverLimitIntent(template)); 522 mOverLimitNotified.add(template); 523 } 524 } 525 526 private void notifyUnderLimitLocked(NetworkTemplate template) { 527 mOverLimitNotified.remove(template); 528 } 529 530 /** 531 * Build unique tag that identifies an active {@link NetworkPolicy} 532 * notification of a specific type, like {@link #TYPE_LIMIT}. 533 */ 534 private String buildNotificationTag(NetworkPolicy policy, int type) { 535 return TAG + ":" + policy.template.hashCode() + ":" + type; 536 } 537 538 /** 539 * Show notification for combined {@link NetworkPolicy} and specific type, 540 * like {@link #TYPE_LIMIT}. Okay to call multiple times. 541 */ 542 private void enqueueNotification(NetworkPolicy policy, int type, long totalBytes) { 543 final String tag = buildNotificationTag(policy, type); 544 final Notification.Builder builder = new Notification.Builder(mContext); 545 builder.setOnlyAlertOnce(true); 546 builder.setOngoing(true); 547 548 final Resources res = mContext.getResources(); 549 switch (type) { 550 case TYPE_WARNING: { 551 final CharSequence title = res.getText(R.string.data_usage_warning_title); 552 final CharSequence body = res.getString(R.string.data_usage_warning_body); 553 554 builder.setSmallIcon(R.drawable.stat_notify_error); 555 builder.setTicker(title); 556 builder.setContentTitle(title); 557 builder.setContentText(body); 558 559 final Intent intent = buildViewDataUsageIntent(policy.template); 560 builder.setContentIntent(PendingIntent.getActivity( 561 mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)); 562 break; 563 } 564 case TYPE_LIMIT: { 565 final CharSequence body = res.getText(R.string.data_usage_limit_body); 566 567 final CharSequence title; 568 switch (policy.template.getMatchRule()) { 569 case MATCH_MOBILE_3G_LOWER: 570 title = res.getText(R.string.data_usage_3g_limit_title); 571 break; 572 case MATCH_MOBILE_4G: 573 title = res.getText(R.string.data_usage_4g_limit_title); 574 break; 575 case MATCH_MOBILE_ALL: 576 title = res.getText(R.string.data_usage_mobile_limit_title); 577 break; 578 case MATCH_WIFI: 579 title = res.getText(R.string.data_usage_wifi_limit_title); 580 break; 581 default: 582 title = null; 583 break; 584 } 585 586 builder.setSmallIcon(R.drawable.stat_notify_disabled); 587 builder.setTicker(title); 588 builder.setContentTitle(title); 589 builder.setContentText(body); 590 591 final Intent intent = buildNetworkOverLimitIntent(policy.template); 592 builder.setContentIntent(PendingIntent.getActivity( 593 mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)); 594 break; 595 } 596 case TYPE_LIMIT_SNOOZED: { 597 final long overBytes = totalBytes - policy.limitBytes; 598 final CharSequence body = res.getString(R.string.data_usage_limit_snoozed_body, 599 Formatter.formatFileSize(mContext, overBytes)); 600 601 final CharSequence title; 602 switch (policy.template.getMatchRule()) { 603 case MATCH_MOBILE_3G_LOWER: 604 title = res.getText(R.string.data_usage_3g_limit_snoozed_title); 605 break; 606 case MATCH_MOBILE_4G: 607 title = res.getText(R.string.data_usage_4g_limit_snoozed_title); 608 break; 609 case MATCH_MOBILE_ALL: 610 title = res.getText(R.string.data_usage_mobile_limit_snoozed_title); 611 break; 612 case MATCH_WIFI: 613 title = res.getText(R.string.data_usage_wifi_limit_snoozed_title); 614 break; 615 default: 616 title = null; 617 break; 618 } 619 620 builder.setSmallIcon(R.drawable.stat_notify_error); 621 builder.setTicker(title); 622 builder.setContentTitle(title); 623 builder.setContentText(body); 624 625 final Intent intent = buildViewDataUsageIntent(policy.template); 626 builder.setContentIntent(PendingIntent.getActivity( 627 mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)); 628 break; 629 } 630 } 631 632 // TODO: move to NotificationManager once we can mock it 633 try { 634 final String packageName = mContext.getPackageName(); 635 final int[] idReceived = new int[1]; 636 mNotifManager.enqueueNotificationWithTag( 637 packageName, tag, 0x0, builder.getNotification(), idReceived); 638 mActiveNotifs.add(tag); 639 } catch (RemoteException e) { 640 // ignored; service lives in system_server 641 } 642 } 643 644 /** 645 * Show ongoing notification to reflect that {@link #mRestrictBackground} 646 * has been enabled. 647 */ 648 private void enqueueRestrictedNotification(String tag) { 649 final Resources res = mContext.getResources(); 650 final Notification.Builder builder = new Notification.Builder(mContext); 651 652 final CharSequence title = res.getText(R.string.data_usage_restricted_title); 653 final CharSequence body = res.getString(R.string.data_usage_restricted_body); 654 655 builder.setOnlyAlertOnce(true); 656 builder.setOngoing(true); 657 builder.setSmallIcon(R.drawable.stat_notify_error); 658 builder.setTicker(title); 659 builder.setContentTitle(title); 660 builder.setContentText(body); 661 662 final Intent intent = buildAllowBackgroundDataIntent(); 663 builder.setContentIntent( 664 PendingIntent.getBroadcast(mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)); 665 666 // TODO: move to NotificationManager once we can mock it 667 try { 668 final String packageName = mContext.getPackageName(); 669 final int[] idReceived = new int[1]; 670 mNotifManager.enqueueNotificationWithTag(packageName, tag, 671 0x0, builder.getNotification(), idReceived); 672 mActiveNotifs.add(tag); 673 } catch (RemoteException e) { 674 // ignored; service lives in system_server 675 } 676 } 677 678 private void cancelNotification(String tag) { 679 // TODO: move to NotificationManager once we can mock it 680 try { 681 final String packageName = mContext.getPackageName(); 682 mNotifManager.cancelNotificationWithTag( 683 packageName, tag, 0x0); 684 } catch (RemoteException e) { 685 // ignored; service lives in system_server 686 } 687 } 688 689 /** 690 * Receiver that watches for {@link IConnectivityManager} to claim network 691 * interfaces. Used to apply {@link NetworkPolicy} to matching networks. 692 */ 693 private BroadcastReceiver mConnReceiver = new BroadcastReceiver() { 694 @Override 695 public void onReceive(Context context, Intent intent) { 696 // on background handler thread, and verified CONNECTIVITY_INTERNAL 697 // permission above. 698 synchronized (mRulesLock) { 699 ensureActiveMobilePolicyLocked(); 700 updateNetworkEnabledLocked(); 701 updateNetworkRulesLocked(); 702 updateNotificationsLocked(); 703 } 704 } 705 }; 706 707 /** 708 * Proactively control network data connections when they exceed 709 * {@link NetworkPolicy#limitBytes}. 710 */ 711 private void updateNetworkEnabledLocked() { 712 if (LOGV) Slog.v(TAG, "updateNetworkEnabledLocked()"); 713 714 // TODO: reset any policy-disabled networks when any policy is removed 715 // completely, which is currently rare case. 716 717 final long currentTime = currentTimeMillis(true); 718 for (NetworkPolicy policy : mNetworkPolicy.values()) { 719 // shortcut when policy has no limit 720 if (policy.limitBytes == LIMIT_DISABLED) { 721 setNetworkTemplateEnabled(policy.template, true); 722 continue; 723 } 724 725 final long start = computeLastCycleBoundary(currentTime, policy); 726 final long end = currentTime; 727 final long totalBytes = getTotalBytes(policy.template, start, end); 728 729 // disable data connection when over limit and not snoozed 730 final boolean overLimit = policy.isOverLimit(totalBytes) && policy.lastSnooze < start; 731 final boolean enabled = !overLimit; 732 733 setNetworkTemplateEnabled(policy.template, enabled); 734 } 735 } 736 737 /** 738 * Control {@link IConnectivityManager#setPolicyDataEnable(int, boolean)} 739 * for the given {@link NetworkTemplate}. 740 */ 741 private void setNetworkTemplateEnabled(NetworkTemplate template, boolean enabled) { 742 switch (template.getMatchRule()) { 743 case MATCH_MOBILE_3G_LOWER: 744 case MATCH_MOBILE_4G: 745 case MATCH_MOBILE_ALL: 746 // TODO: offer more granular control over radio states once 747 // 4965893 is available. 748 if (Objects.equal(getActiveSubscriberId(), template.getSubscriberId())) { 749 setPolicyDataEnable(TYPE_MOBILE, enabled); 750 setPolicyDataEnable(TYPE_WIMAX, enabled); 751 } 752 break; 753 case MATCH_WIFI: 754 setPolicyDataEnable(TYPE_WIFI, enabled); 755 break; 756 case MATCH_ETHERNET: 757 setPolicyDataEnable(TYPE_ETHERNET, enabled); 758 break; 759 default: 760 throw new IllegalArgumentException("unexpected template"); 761 } 762 } 763 764 /** 765 * Examine all connected {@link NetworkState}, looking for 766 * {@link NetworkPolicy} that need to be enforced. When matches found, set 767 * remaining quota based on usage cycle and historical stats. 768 */ 769 private void updateNetworkRulesLocked() { 770 if (LOGV) Slog.v(TAG, "updateIfacesLocked()"); 771 772 final NetworkState[] states; 773 try { 774 states = mConnManager.getAllNetworkState(); 775 } catch (RemoteException e) { 776 // ignored; service lives in system_server 777 return; 778 } 779 780 // first, derive identity for all connected networks, which can be used 781 // to match against templates. 782 final HashMap<NetworkIdentity, String> networks = Maps.newHashMap(); 783 for (NetworkState state : states) { 784 // stash identity and iface away for later use 785 if (state.networkInfo.isConnected()) { 786 final String iface = state.linkProperties.getInterfaceName(); 787 final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state); 788 networks.put(ident, iface); 789 } 790 } 791 792 // build list of rules and ifaces to enforce them against 793 mNetworkRules.clear(); 794 final ArrayList<String> ifaceList = Lists.newArrayList(); 795 for (NetworkPolicy policy : mNetworkPolicy.values()) { 796 797 // collect all active ifaces that match this template 798 ifaceList.clear(); 799 for (Map.Entry<NetworkIdentity, String> entry : networks.entrySet()) { 800 final NetworkIdentity ident = entry.getKey(); 801 if (policy.template.matches(ident)) { 802 final String iface = entry.getValue(); 803 ifaceList.add(iface); 804 } 805 } 806 807 if (ifaceList.size() > 0) { 808 final String[] ifaces = ifaceList.toArray(new String[ifaceList.size()]); 809 mNetworkRules.put(policy, ifaces); 810 } 811 } 812 813 final HashSet<String> newMeteredIfaces = Sets.newHashSet(); 814 815 // apply each policy that we found ifaces for; compute remaining data 816 // based on current cycle and historical stats, and push to kernel. 817 final long currentTime = currentTimeMillis(true); 818 for (NetworkPolicy policy : mNetworkRules.keySet()) { 819 final String[] ifaces = mNetworkRules.get(policy); 820 821 final long start = computeLastCycleBoundary(currentTime, policy); 822 final long end = currentTime; 823 final long totalBytes = getTotalBytes(policy.template, start, end); 824 825 if (LOGD) { 826 Slog.d(TAG, "applying policy " + policy.toString() + " to ifaces " 827 + Arrays.toString(ifaces)); 828 } 829 830 final boolean hasLimit = policy.limitBytes != LIMIT_DISABLED; 831 if (hasLimit) { 832 final long quotaBytes; 833 if (policy.lastSnooze >= start) { 834 // snoozing past quota, but we still need to restrict apps, 835 // so push really high quota. 836 quotaBytes = Long.MAX_VALUE; 837 } else { 838 // remaining "quota" bytes are based on total usage in 839 // current cycle. kernel doesn't like 0-byte rules, so we 840 // set 1-byte quota and disable the radio later. 841 quotaBytes = Math.max(1, policy.limitBytes - totalBytes); 842 } 843 844 if (ifaces.length > 1) { 845 // TODO: switch to shared quota once NMS supports 846 Slog.w(TAG, "shared quota unsupported; generating rule for each iface"); 847 } 848 849 for (String iface : ifaces) { 850 removeInterfaceQuota(iface); 851 setInterfaceQuota(iface, quotaBytes); 852 newMeteredIfaces.add(iface); 853 } 854 } 855 } 856 857 // remove quota on any trailing interfaces 858 for (String iface : mMeteredIfaces) { 859 if (!newMeteredIfaces.contains(iface)) { 860 removeInterfaceQuota(iface); 861 } 862 } 863 mMeteredIfaces = newMeteredIfaces; 864 865 final String[] meteredIfaces = mMeteredIfaces.toArray(new String[mMeteredIfaces.size()]); 866 mHandler.obtainMessage(MSG_METERED_IFACES_CHANGED, meteredIfaces).sendToTarget(); 867 } 868 869 /** 870 * Once any {@link #mNetworkPolicy} are loaded from disk, ensure that we 871 * have at least a default mobile policy defined. 872 */ 873 private void ensureActiveMobilePolicyLocked() { 874 if (LOGV) Slog.v(TAG, "ensureActiveMobilePolicyLocked()"); 875 if (mSuppressDefaultPolicy) return; 876 877 final String subscriberId = getActiveSubscriberId(); 878 final NetworkIdentity probeIdent = new NetworkIdentity( 879 TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, false); 880 881 // examine to see if any policy is defined for active mobile 882 boolean mobileDefined = false; 883 for (NetworkPolicy policy : mNetworkPolicy.values()) { 884 if (policy.template.matches(probeIdent)) { 885 mobileDefined = true; 886 } 887 } 888 889 if (!mobileDefined) { 890 Slog.i(TAG, "no policy for active mobile network; generating default policy"); 891 892 // build default mobile policy, and assume usage cycle starts today 893 final long warningBytes = mContext.getResources().getInteger( 894 com.android.internal.R.integer.config_networkPolicyDefaultWarning) 895 * MB_IN_BYTES; 896 897 final Time time = new Time(Time.TIMEZONE_UTC); 898 time.setToNow(); 899 final int cycleDay = time.monthDay; 900 901 final NetworkTemplate template = buildTemplateMobileAll(subscriberId); 902 mNetworkPolicy.put(template, new NetworkPolicy( 903 template, cycleDay, warningBytes, LIMIT_DISABLED, SNOOZE_NEVER)); 904 writePolicyLocked(); 905 } 906 } 907 908 private void readPolicyLocked() { 909 if (LOGV) Slog.v(TAG, "readPolicyLocked()"); 910 911 // clear any existing policy and read from disk 912 mNetworkPolicy.clear(); 913 mUidPolicy.clear(); 914 915 FileInputStream fis = null; 916 try { 917 fis = mPolicyFile.openRead(); 918 final XmlPullParser in = Xml.newPullParser(); 919 in.setInput(fis, null); 920 921 int type; 922 int version = VERSION_INIT; 923 while ((type = in.next()) != END_DOCUMENT) { 924 final String tag = in.getName(); 925 if (type == START_TAG) { 926 if (TAG_POLICY_LIST.equals(tag)) { 927 version = readIntAttribute(in, ATTR_VERSION); 928 if (version >= VERSION_ADDED_RESTRICT_BACKGROUND) { 929 mRestrictBackground = readBooleanAttribute( 930 in, ATTR_RESTRICT_BACKGROUND); 931 } else { 932 mRestrictBackground = false; 933 } 934 935 } else if (TAG_NETWORK_POLICY.equals(tag)) { 936 final int networkTemplate = readIntAttribute(in, ATTR_NETWORK_TEMPLATE); 937 final String subscriberId = in.getAttributeValue(null, ATTR_SUBSCRIBER_ID); 938 final int cycleDay = readIntAttribute(in, ATTR_CYCLE_DAY); 939 final long warningBytes = readLongAttribute(in, ATTR_WARNING_BYTES); 940 final long limitBytes = readLongAttribute(in, ATTR_LIMIT_BYTES); 941 final long lastSnooze; 942 if (version >= VERSION_ADDED_SNOOZE) { 943 lastSnooze = readLongAttribute(in, ATTR_LAST_SNOOZE); 944 } else { 945 lastSnooze = SNOOZE_NEVER; 946 } 947 948 final NetworkTemplate template = new NetworkTemplate( 949 networkTemplate, subscriberId); 950 mNetworkPolicy.put(template, new NetworkPolicy( 951 template, cycleDay, warningBytes, limitBytes, lastSnooze)); 952 953 } else if (TAG_UID_POLICY.equals(tag)) { 954 final int uid = readIntAttribute(in, ATTR_UID); 955 final int policy = readIntAttribute(in, ATTR_POLICY); 956 957 if (isUidValidForPolicy(mContext, uid)) { 958 setUidPolicyUnchecked(uid, policy, false); 959 } else { 960 Slog.w(TAG, "unable to apply policy to UID " + uid + "; ignoring"); 961 } 962 } 963 } 964 } 965 966 } catch (FileNotFoundException e) { 967 // missing policy is okay, probably first boot 968 upgradeLegacyBackgroundData(); 969 } catch (IOException e) { 970 Log.wtf(TAG, "problem reading network policy", e); 971 } catch (XmlPullParserException e) { 972 Log.wtf(TAG, "problem reading network policy", e); 973 } finally { 974 IoUtils.closeQuietly(fis); 975 } 976 } 977 978 /** 979 * Upgrade legacy background data flags, notifying listeners of one last 980 * change to always-true. 981 */ 982 private void upgradeLegacyBackgroundData() { 983 mRestrictBackground = Settings.Secure.getInt( 984 mContext.getContentResolver(), Settings.Secure.BACKGROUND_DATA, 1) != 1; 985 986 // kick off one last broadcast if restricted 987 if (mRestrictBackground) { 988 final Intent broadcast = new Intent( 989 ConnectivityManager.ACTION_BACKGROUND_DATA_SETTING_CHANGED); 990 mContext.sendBroadcast(broadcast); 991 } 992 } 993 994 private void writePolicyLocked() { 995 if (LOGV) Slog.v(TAG, "writePolicyLocked()"); 996 997 FileOutputStream fos = null; 998 try { 999 fos = mPolicyFile.startWrite(); 1000 1001 XmlSerializer out = new FastXmlSerializer(); 1002 out.setOutput(fos, "utf-8"); 1003 out.startDocument(null, true); 1004 1005 out.startTag(null, TAG_POLICY_LIST); 1006 writeIntAttribute(out, ATTR_VERSION, VERSION_ADDED_RESTRICT_BACKGROUND); 1007 writeBooleanAttribute(out, ATTR_RESTRICT_BACKGROUND, mRestrictBackground); 1008 1009 // write all known network policies 1010 for (NetworkPolicy policy : mNetworkPolicy.values()) { 1011 final NetworkTemplate template = policy.template; 1012 1013 out.startTag(null, TAG_NETWORK_POLICY); 1014 writeIntAttribute(out, ATTR_NETWORK_TEMPLATE, template.getMatchRule()); 1015 final String subscriberId = template.getSubscriberId(); 1016 if (subscriberId != null) { 1017 out.attribute(null, ATTR_SUBSCRIBER_ID, subscriberId); 1018 } 1019 writeIntAttribute(out, ATTR_CYCLE_DAY, policy.cycleDay); 1020 writeLongAttribute(out, ATTR_WARNING_BYTES, policy.warningBytes); 1021 writeLongAttribute(out, ATTR_LIMIT_BYTES, policy.limitBytes); 1022 writeLongAttribute(out, ATTR_LAST_SNOOZE, policy.lastSnooze); 1023 out.endTag(null, TAG_NETWORK_POLICY); 1024 } 1025 1026 // write all known uid policies 1027 for (int i = 0; i < mUidPolicy.size(); i++) { 1028 final int uid = mUidPolicy.keyAt(i); 1029 final int policy = mUidPolicy.valueAt(i); 1030 1031 // skip writing empty policies 1032 if (policy == POLICY_NONE) continue; 1033 1034 out.startTag(null, TAG_UID_POLICY); 1035 writeIntAttribute(out, ATTR_UID, uid); 1036 writeIntAttribute(out, ATTR_POLICY, policy); 1037 out.endTag(null, TAG_UID_POLICY); 1038 } 1039 1040 out.endTag(null, TAG_POLICY_LIST); 1041 out.endDocument(); 1042 1043 mPolicyFile.finishWrite(fos); 1044 } catch (IOException e) { 1045 if (fos != null) { 1046 mPolicyFile.failWrite(fos); 1047 } 1048 } 1049 } 1050 1051 @Override 1052 public void setUidPolicy(int uid, int policy) { 1053 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 1054 1055 if (!isUidValidForPolicy(mContext, uid)) { 1056 throw new IllegalArgumentException("cannot apply policy to UID " + uid); 1057 } 1058 1059 setUidPolicyUnchecked(uid, policy, true); 1060 } 1061 1062 private void setUidPolicyUnchecked(int uid, int policy, boolean persist) { 1063 final int oldPolicy; 1064 synchronized (mRulesLock) { 1065 oldPolicy = getUidPolicy(uid); 1066 mUidPolicy.put(uid, policy); 1067 1068 // uid policy changed, recompute rules and persist policy. 1069 updateRulesForUidLocked(uid); 1070 if (persist) { 1071 writePolicyLocked(); 1072 } 1073 } 1074 } 1075 1076 @Override 1077 public int getUidPolicy(int uid) { 1078 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 1079 1080 synchronized (mRulesLock) { 1081 return mUidPolicy.get(uid, POLICY_NONE); 1082 } 1083 } 1084 1085 @Override 1086 public void registerListener(INetworkPolicyListener listener) { 1087 // TODO: create permission for observing network policy 1088 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 1089 1090 mListeners.register(listener); 1091 1092 // TODO: consider dispatching existing rules to new listeners 1093 } 1094 1095 @Override 1096 public void unregisterListener(INetworkPolicyListener listener) { 1097 // TODO: create permission for observing network policy 1098 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 1099 1100 mListeners.unregister(listener); 1101 } 1102 1103 @Override 1104 public void setNetworkPolicies(NetworkPolicy[] policies) { 1105 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 1106 1107 synchronized (mRulesLock) { 1108 mNetworkPolicy.clear(); 1109 for (NetworkPolicy policy : policies) { 1110 mNetworkPolicy.put(policy.template, policy); 1111 } 1112 1113 updateNetworkEnabledLocked(); 1114 updateNetworkRulesLocked(); 1115 updateNotificationsLocked(); 1116 writePolicyLocked(); 1117 } 1118 } 1119 1120 @Override 1121 public NetworkPolicy[] getNetworkPolicies() { 1122 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 1123 mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, TAG); 1124 1125 synchronized (mRulesLock) { 1126 return mNetworkPolicy.values().toArray(new NetworkPolicy[mNetworkPolicy.size()]); 1127 } 1128 } 1129 1130 @Override 1131 public void snoozePolicy(NetworkTemplate template) { 1132 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 1133 1134 final long currentTime = currentTimeMillis(true); 1135 synchronized (mRulesLock) { 1136 // find and snooze local policy that matches 1137 final NetworkPolicy policy = mNetworkPolicy.get(template); 1138 if (policy == null) { 1139 throw new IllegalArgumentException("unable to find policy for " + template); 1140 } 1141 1142 policy.lastSnooze = currentTime; 1143 1144 updateNetworkEnabledLocked(); 1145 updateNetworkRulesLocked(); 1146 updateNotificationsLocked(); 1147 writePolicyLocked(); 1148 } 1149 } 1150 1151 @Override 1152 public void setRestrictBackground(boolean restrictBackground) { 1153 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 1154 1155 synchronized (mRulesLock) { 1156 mRestrictBackground = restrictBackground; 1157 updateRulesForRestrictBackgroundLocked(); 1158 updateNotificationsLocked(); 1159 writePolicyLocked(); 1160 } 1161 } 1162 1163 @Override 1164 public boolean getRestrictBackground() { 1165 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 1166 1167 synchronized (mRulesLock) { 1168 return mRestrictBackground; 1169 } 1170 } 1171 1172 private NetworkPolicy findPolicyForNetworkLocked(NetworkIdentity ident) { 1173 for (NetworkPolicy policy : mNetworkPolicy.values()) { 1174 if (policy.template.matches(ident)) { 1175 return policy; 1176 } 1177 } 1178 return null; 1179 } 1180 1181 @Override 1182 public NetworkQuotaInfo getNetworkQuotaInfo(NetworkState state) { 1183 mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG); 1184 1185 // only returns usage summary, so we don't require caller to have 1186 // READ_NETWORK_USAGE_HISTORY. 1187 final long token = Binder.clearCallingIdentity(); 1188 try { 1189 return getNetworkQuotaInfoUnchecked(state); 1190 } finally { 1191 Binder.restoreCallingIdentity(token); 1192 } 1193 } 1194 1195 private NetworkQuotaInfo getNetworkQuotaInfoUnchecked(NetworkState state) { 1196 final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state); 1197 1198 final NetworkPolicy policy; 1199 synchronized (mRulesLock) { 1200 policy = findPolicyForNetworkLocked(ident); 1201 } 1202 1203 if (policy == null) { 1204 // missing policy means we can't derive useful quota info 1205 return null; 1206 } 1207 1208 final long currentTime = currentTimeMillis(false); 1209 1210 // find total bytes used under policy 1211 final long start = computeLastCycleBoundary(currentTime, policy); 1212 final long end = currentTime; 1213 final long totalBytes = getTotalBytes(policy.template, start, end); 1214 1215 // report soft and hard limits under policy 1216 final long softLimitBytes = policy.warningBytes != WARNING_DISABLED ? policy.warningBytes 1217 : NetworkQuotaInfo.NO_LIMIT; 1218 final long hardLimitBytes = policy.limitBytes != LIMIT_DISABLED ? policy.limitBytes 1219 : NetworkQuotaInfo.NO_LIMIT; 1220 1221 return new NetworkQuotaInfo(totalBytes, softLimitBytes, hardLimitBytes); 1222 } 1223 1224 @Override 1225 protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) { 1226 mContext.enforceCallingOrSelfPermission(DUMP, TAG); 1227 1228 final HashSet<String> argSet = new HashSet<String>(); 1229 for (String arg : args) { 1230 argSet.add(arg); 1231 } 1232 1233 synchronized (mRulesLock) { 1234 if (argSet.contains("unsnooze")) { 1235 for (NetworkPolicy policy : mNetworkPolicy.values()) { 1236 policy.lastSnooze = SNOOZE_NEVER; 1237 } 1238 writePolicyLocked(); 1239 fout.println("Wiped snooze timestamps"); 1240 return; 1241 } 1242 1243 fout.print("Restrict background: "); fout.println(mRestrictBackground); 1244 fout.println("Network policies:"); 1245 for (NetworkPolicy policy : mNetworkPolicy.values()) { 1246 fout.print(" "); fout.println(policy.toString()); 1247 } 1248 1249 fout.println("Policy status for known UIDs:"); 1250 1251 final SparseBooleanArray knownUids = new SparseBooleanArray(); 1252 collectKeys(mUidPolicy, knownUids); 1253 collectKeys(mUidForeground, knownUids); 1254 collectKeys(mUidRules, knownUids); 1255 1256 final int size = knownUids.size(); 1257 for (int i = 0; i < size; i++) { 1258 final int uid = knownUids.keyAt(i); 1259 fout.print(" UID="); 1260 fout.print(uid); 1261 1262 fout.print(" policy="); 1263 final int policyIndex = mUidPolicy.indexOfKey(uid); 1264 if (policyIndex < 0) { 1265 fout.print("UNKNOWN"); 1266 } else { 1267 dumpPolicy(fout, mUidPolicy.valueAt(policyIndex)); 1268 } 1269 1270 fout.print(" foreground="); 1271 final int foregroundIndex = mUidPidForeground.indexOfKey(uid); 1272 if (foregroundIndex < 0) { 1273 fout.print("UNKNOWN"); 1274 } else { 1275 dumpSparseBooleanArray(fout, mUidPidForeground.valueAt(foregroundIndex)); 1276 } 1277 1278 fout.print(" rules="); 1279 final int rulesIndex = mUidRules.indexOfKey(uid); 1280 if (rulesIndex < 0) { 1281 fout.print("UNKNOWN"); 1282 } else { 1283 dumpRules(fout, mUidRules.valueAt(rulesIndex)); 1284 } 1285 1286 fout.println(); 1287 } 1288 } 1289 } 1290 1291 @Override 1292 public boolean isUidForeground(int uid) { 1293 mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); 1294 1295 synchronized (mRulesLock) { 1296 // only really in foreground when screen is also on 1297 return mUidForeground.get(uid, false) && mScreenOn; 1298 } 1299 } 1300 1301 /** 1302 * Foreground for PID changed; recompute foreground at UID level. If 1303 * changed, will trigger {@link #updateRulesForUidLocked(int)}. 1304 */ 1305 private void computeUidForegroundLocked(int uid) { 1306 final SparseBooleanArray pidForeground = mUidPidForeground.get(uid); 1307 1308 // current pid is dropping foreground; examine other pids 1309 boolean uidForeground = false; 1310 final int size = pidForeground.size(); 1311 for (int i = 0; i < size; i++) { 1312 if (pidForeground.valueAt(i)) { 1313 uidForeground = true; 1314 break; 1315 } 1316 } 1317 1318 final boolean oldUidForeground = mUidForeground.get(uid, false); 1319 if (oldUidForeground != uidForeground) { 1320 // foreground changed, push updated rules 1321 mUidForeground.put(uid, uidForeground); 1322 updateRulesForUidLocked(uid); 1323 } 1324 } 1325 1326 private void updateScreenOn() { 1327 synchronized (mRulesLock) { 1328 try { 1329 mScreenOn = mPowerManager.isScreenOn(); 1330 } catch (RemoteException e) { 1331 // ignored; service lives in system_server 1332 } 1333 updateRulesForScreenLocked(); 1334 } 1335 } 1336 1337 /** 1338 * Update rules that might be changed by {@link #mScreenOn} value. 1339 */ 1340 private void updateRulesForScreenLocked() { 1341 // only update rules for anyone with foreground activities 1342 final int size = mUidForeground.size(); 1343 for (int i = 0; i < size; i++) { 1344 if (mUidForeground.valueAt(i)) { 1345 final int uid = mUidForeground.keyAt(i); 1346 updateRulesForUidLocked(uid); 1347 } 1348 } 1349 } 1350 1351 /** 1352 * Update rules that might be changed by {@link #mRestrictBackground} value. 1353 */ 1354 private void updateRulesForRestrictBackgroundLocked() { 1355 // update rules for all installed applications 1356 final PackageManager pm = mContext.getPackageManager(); 1357 final List<ApplicationInfo> apps = pm.getInstalledApplications(0); 1358 for (ApplicationInfo app : apps) { 1359 updateRulesForUidLocked(app.uid); 1360 } 1361 1362 // and catch system UIDs 1363 // TODO: keep in sync with android_filesystem_config.h 1364 for (int uid = 1000; uid <= 1025; uid++) { 1365 updateRulesForUidLocked(uid); 1366 } 1367 for (int uid = 2000; uid <= 2002; uid++) { 1368 updateRulesForUidLocked(uid); 1369 } 1370 for (int uid = 3000; uid <= 3007; uid++) { 1371 updateRulesForUidLocked(uid); 1372 } 1373 for (int uid = 9998; uid <= 9999; uid++) { 1374 updateRulesForUidLocked(uid); 1375 } 1376 } 1377 1378 private void updateRulesForUidLocked(int uid) { 1379 final int uidPolicy = getUidPolicy(uid); 1380 final boolean uidForeground = isUidForeground(uid); 1381 1382 // derive active rules based on policy and active state 1383 int uidRules = RULE_ALLOW_ALL; 1384 if (!uidForeground && (uidPolicy & POLICY_REJECT_METERED_BACKGROUND) != 0) { 1385 // uid in background, and policy says to block metered data 1386 uidRules = RULE_REJECT_METERED; 1387 } 1388 if (!uidForeground && mRestrictBackground) { 1389 // uid in background, and global background disabled 1390 uidRules = RULE_REJECT_METERED; 1391 } 1392 1393 // TODO: only dispatch when rules actually change 1394 1395 if (uidRules == RULE_ALLOW_ALL) { 1396 mUidRules.delete(uid); 1397 } else { 1398 mUidRules.put(uid, uidRules); 1399 } 1400 1401 final boolean rejectMetered = (uidRules & RULE_REJECT_METERED) != 0; 1402 setUidNetworkRules(uid, rejectMetered); 1403 1404 // dispatch changed rule to existing listeners 1405 mHandler.obtainMessage(MSG_RULES_CHANGED, uid, uidRules).sendToTarget(); 1406 1407 try { 1408 // adjust stats accounting based on foreground status 1409 mNetworkStats.setUidForeground(uid, uidForeground); 1410 } catch (RemoteException e) { 1411 // ignored; service lives in system_server 1412 } 1413 } 1414 1415 private Handler.Callback mHandlerCallback = new Handler.Callback() { 1416 /** {@inheritDoc} */ 1417 public boolean handleMessage(Message msg) { 1418 switch (msg.what) { 1419 case MSG_RULES_CHANGED: { 1420 final int uid = msg.arg1; 1421 final int uidRules = msg.arg2; 1422 final int length = mListeners.beginBroadcast(); 1423 for (int i = 0; i < length; i++) { 1424 final INetworkPolicyListener listener = mListeners.getBroadcastItem(i); 1425 if (listener != null) { 1426 try { 1427 listener.onUidRulesChanged(uid, uidRules); 1428 } catch (RemoteException e) { 1429 } 1430 } 1431 } 1432 mListeners.finishBroadcast(); 1433 return true; 1434 } 1435 case MSG_METERED_IFACES_CHANGED: { 1436 final String[] meteredIfaces = (String[]) msg.obj; 1437 final int length = mListeners.beginBroadcast(); 1438 for (int i = 0; i < length; i++) { 1439 final INetworkPolicyListener listener = mListeners.getBroadcastItem(i); 1440 if (listener != null) { 1441 try { 1442 listener.onMeteredIfacesChanged(meteredIfaces); 1443 } catch (RemoteException e) { 1444 } 1445 } 1446 } 1447 mListeners.finishBroadcast(); 1448 return true; 1449 } 1450 case MSG_FOREGROUND_ACTIVITIES_CHANGED: { 1451 final int pid = msg.arg1; 1452 final int uid = msg.arg2; 1453 final boolean foregroundActivities = (Boolean) msg.obj; 1454 1455 synchronized (mRulesLock) { 1456 // because a uid can have multiple pids running inside, we need to 1457 // remember all pid states and summarize foreground at uid level. 1458 1459 // record foreground for this specific pid 1460 SparseBooleanArray pidForeground = mUidPidForeground.get(uid); 1461 if (pidForeground == null) { 1462 pidForeground = new SparseBooleanArray(2); 1463 mUidPidForeground.put(uid, pidForeground); 1464 } 1465 pidForeground.put(pid, foregroundActivities); 1466 computeUidForegroundLocked(uid); 1467 } 1468 return true; 1469 } 1470 case MSG_PROCESS_DIED: { 1471 final int pid = msg.arg1; 1472 final int uid = msg.arg2; 1473 1474 synchronized (mRulesLock) { 1475 // clear records and recompute, when they exist 1476 final SparseBooleanArray pidForeground = mUidPidForeground.get(uid); 1477 if (pidForeground != null) { 1478 pidForeground.delete(pid); 1479 computeUidForegroundLocked(uid); 1480 } 1481 } 1482 return true; 1483 } 1484 default: { 1485 return false; 1486 } 1487 } 1488 } 1489 }; 1490 1491 private void setInterfaceQuota(String iface, long quotaBytes) { 1492 try { 1493 mNetworkManager.setInterfaceQuota(iface, quotaBytes); 1494 } catch (IllegalStateException e) { 1495 Log.wtf(TAG, "problem setting interface quota", e); 1496 } catch (RemoteException e) { 1497 // ignored; service lives in system_server 1498 } 1499 } 1500 1501 private void removeInterfaceQuota(String iface) { 1502 try { 1503 mNetworkManager.removeInterfaceQuota(iface); 1504 } catch (IllegalStateException e) { 1505 Log.wtf(TAG, "problem removing interface quota", e); 1506 } catch (RemoteException e) { 1507 // ignored; service lives in system_server 1508 } 1509 } 1510 1511 private void setUidNetworkRules(int uid, boolean rejectOnQuotaInterfaces) { 1512 try { 1513 mNetworkManager.setUidNetworkRules(uid, rejectOnQuotaInterfaces); 1514 } catch (IllegalStateException e) { 1515 Log.wtf(TAG, "problem setting uid rules", e); 1516 } catch (RemoteException e) { 1517 // ignored; service lives in system_server 1518 } 1519 } 1520 1521 /** 1522 * Control {@link IConnectivityManager#setPolicyDataEnable(int, boolean)}, 1523 * dispatching only when actually changed. 1524 */ 1525 private void setPolicyDataEnable(int networkType, boolean enabled) { 1526 synchronized (mActiveNetworkEnabled) { 1527 final boolean prevEnabled = mActiveNetworkEnabled.get(networkType, true); 1528 if (prevEnabled == enabled) return; 1529 1530 try { 1531 mConnManager.setPolicyDataEnable(networkType, enabled); 1532 } catch (RemoteException e) { 1533 // ignored; service lives in system_server 1534 } 1535 1536 mActiveNetworkEnabled.put(networkType, enabled); 1537 } 1538 } 1539 1540 private String getActiveSubscriberId() { 1541 final TelephonyManager telephony = (TelephonyManager) mContext.getSystemService( 1542 Context.TELEPHONY_SERVICE); 1543 return telephony.getSubscriberId(); 1544 } 1545 1546 private long getTotalBytes(NetworkTemplate template, long start, long end) { 1547 try { 1548 return mNetworkStats.getSummaryForNetwork(template, start, end).getTotalBytes(); 1549 } catch (RemoteException e) { 1550 // ignored; service lives in system_server 1551 return 0; 1552 } 1553 } 1554 1555 private long currentTimeMillis(boolean allowRefresh) { 1556 // try refreshing time source when stale 1557 if (mTime.getCacheAge() > TIME_CACHE_MAX_AGE && allowRefresh) { 1558 mTime.forceRefresh(); 1559 } 1560 1561 return mTime.hasCache() ? mTime.currentTimeMillis() : System.currentTimeMillis(); 1562 } 1563 1564 private static Intent buildAllowBackgroundDataIntent() { 1565 return new Intent(ACTION_ALLOW_BACKGROUND); 1566 } 1567 1568 private static Intent buildNetworkOverLimitIntent(NetworkTemplate template) { 1569 final Intent intent = new Intent(); 1570 intent.setComponent(new ComponentName( 1571 "com.android.systemui", "com.android.systemui.net.NetworkOverLimitActivity")); 1572 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 1573 intent.putExtra(EXTRA_NETWORK_TEMPLATE, template); 1574 return intent; 1575 } 1576 1577 private static Intent buildViewDataUsageIntent(NetworkTemplate template) { 1578 final Intent intent = new Intent(); 1579 intent.setComponent(new ComponentName( 1580 "com.android.settings", "com.android.settings.Settings$DataUsageSummaryActivity")); 1581 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 1582 intent.putExtra(EXTRA_NETWORK_TEMPLATE, template); 1583 return intent; 1584 } 1585 1586 private static void collectKeys(SparseIntArray source, SparseBooleanArray target) { 1587 final int size = source.size(); 1588 for (int i = 0; i < size; i++) { 1589 target.put(source.keyAt(i), true); 1590 } 1591 } 1592 1593 private static void collectKeys(SparseBooleanArray source, SparseBooleanArray target) { 1594 final int size = source.size(); 1595 for (int i = 0; i < size; i++) { 1596 target.put(source.keyAt(i), true); 1597 } 1598 } 1599 1600 private static void dumpSparseBooleanArray(PrintWriter fout, SparseBooleanArray value) { 1601 fout.print("["); 1602 final int size = value.size(); 1603 for (int i = 0; i < size; i++) { 1604 fout.print(value.keyAt(i) + "=" + value.valueAt(i)); 1605 if (i < size - 1) fout.print(","); 1606 } 1607 fout.print("]"); 1608 } 1609 1610 public static class XmlUtils { 1611 public static int readIntAttribute(XmlPullParser in, String name) throws IOException { 1612 final String value = in.getAttributeValue(null, name); 1613 try { 1614 return Integer.parseInt(value); 1615 } catch (NumberFormatException e) { 1616 throw new ProtocolException("problem parsing " + name + "=" + value + " as int"); 1617 } 1618 } 1619 1620 public static void writeIntAttribute(XmlSerializer out, String name, int value) 1621 throws IOException { 1622 out.attribute(null, name, Integer.toString(value)); 1623 } 1624 1625 public static long readLongAttribute(XmlPullParser in, String name) throws IOException { 1626 final String value = in.getAttributeValue(null, name); 1627 try { 1628 return Long.parseLong(value); 1629 } catch (NumberFormatException e) { 1630 throw new ProtocolException("problem parsing " + name + "=" + value + " as long"); 1631 } 1632 } 1633 1634 public static void writeLongAttribute(XmlSerializer out, String name, long value) 1635 throws IOException { 1636 out.attribute(null, name, Long.toString(value)); 1637 } 1638 1639 public static boolean readBooleanAttribute(XmlPullParser in, String name) { 1640 final String value = in.getAttributeValue(null, name); 1641 return Boolean.parseBoolean(value); 1642 } 1643 1644 public static void writeBooleanAttribute(XmlSerializer out, String name, boolean value) 1645 throws IOException { 1646 out.attribute(null, name, Boolean.toString(value)); 1647 } 1648 } 1649 } 1650