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