NetworkPolicyManagerServiceTest.java revision 163e6443f27884a9bfcb9a48ef606dc635852c23
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; 18 19import static android.content.Intent.ACTION_UID_REMOVED; 20import static android.content.Intent.EXTRA_UID; 21import static android.net.ConnectivityManager.CONNECTIVITY_ACTION_IMMEDIATE; 22import static android.net.ConnectivityManager.TYPE_WIFI; 23import static android.net.NetworkPolicy.LIMIT_DISABLED; 24import static android.net.NetworkPolicy.SNOOZE_NEVER; 25import static android.net.NetworkPolicy.WARNING_DISABLED; 26import static android.net.NetworkPolicyManager.POLICY_NONE; 27import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND; 28import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL; 29import static android.net.NetworkPolicyManager.RULE_REJECT_METERED; 30import static android.net.NetworkPolicyManager.computeLastCycleBoundary; 31import static android.net.NetworkPolicyManager.computeNextCycleBoundary; 32import static android.text.format.DateUtils.DAY_IN_MILLIS; 33import static android.text.format.DateUtils.MINUTE_IN_MILLIS; 34import static com.android.server.net.NetworkPolicyManagerService.TYPE_LIMIT; 35import static com.android.server.net.NetworkPolicyManagerService.TYPE_LIMIT_SNOOZED; 36import static com.android.server.net.NetworkPolicyManagerService.TYPE_WARNING; 37import static org.easymock.EasyMock.anyInt; 38import static org.easymock.EasyMock.aryEq; 39import static org.easymock.EasyMock.capture; 40import static org.easymock.EasyMock.createMock; 41import static org.easymock.EasyMock.eq; 42import static org.easymock.EasyMock.expect; 43import static org.easymock.EasyMock.expectLastCall; 44import static org.easymock.EasyMock.isA; 45 46import android.app.IActivityManager; 47import android.app.INotificationManager; 48import android.app.IProcessObserver; 49import android.app.Notification; 50import android.content.Intent; 51import android.content.pm.PackageInfo; 52import android.content.pm.PackageManager; 53import android.content.pm.Signature; 54import android.net.ConnectivityManager; 55import android.net.IConnectivityManager; 56import android.net.INetworkManagementEventObserver; 57import android.net.INetworkPolicyListener; 58import android.net.INetworkStatsService; 59import android.net.LinkProperties; 60import android.net.NetworkInfo; 61import android.net.NetworkInfo.DetailedState; 62import android.net.NetworkPolicy; 63import android.net.NetworkState; 64import android.net.NetworkStats; 65import android.net.NetworkTemplate; 66import android.os.Binder; 67import android.os.INetworkManagementService; 68import android.os.IPowerManager; 69import android.os.MessageQueue.IdleHandler; 70import android.test.AndroidTestCase; 71import android.test.mock.MockPackageManager; 72import android.test.suitebuilder.annotation.LargeTest; 73import android.test.suitebuilder.annotation.Suppress; 74import android.text.format.Time; 75import android.util.TrustedTime; 76 77import com.android.server.net.NetworkPolicyManagerService; 78import com.google.common.util.concurrent.AbstractFuture; 79 80import org.easymock.Capture; 81import org.easymock.EasyMock; 82import org.easymock.IAnswer; 83import org.easymock.IExpectationSetters; 84 85import java.io.File; 86import java.util.LinkedHashSet; 87import java.util.concurrent.ExecutionException; 88import java.util.concurrent.Future; 89import java.util.concurrent.TimeUnit; 90import java.util.concurrent.TimeoutException; 91import java.util.logging.Handler; 92 93import libcore.io.IoUtils; 94 95/** 96 * Tests for {@link NetworkPolicyManagerService}. 97 */ 98@LargeTest 99public class NetworkPolicyManagerServiceTest extends AndroidTestCase { 100 private static final String TAG = "NetworkPolicyManagerServiceTest"; 101 102 private static final long TEST_START = 1194220800000L; 103 private static final String TEST_IFACE = "test0"; 104 105 private static final long KB_IN_BYTES = 1024; 106 private static final long MB_IN_BYTES = KB_IN_BYTES * 1024; 107 private static final long GB_IN_BYTES = MB_IN_BYTES * 1024; 108 109 private static NetworkTemplate sTemplateWifi = NetworkTemplate.buildTemplateWifi(); 110 111 private BroadcastInterceptingContext mServiceContext; 112 private File mPolicyDir; 113 114 private IActivityManager mActivityManager; 115 private IPowerManager mPowerManager; 116 private INetworkStatsService mStatsService; 117 private INetworkManagementService mNetworkManager; 118 private INetworkPolicyListener mPolicyListener; 119 private TrustedTime mTime; 120 private IConnectivityManager mConnManager; 121 private INotificationManager mNotifManager; 122 123 private NetworkPolicyManagerService mService; 124 private IProcessObserver mProcessObserver; 125 private INetworkManagementEventObserver mNetworkObserver; 126 127 private Binder mStubBinder = new Binder(); 128 129 private long mStartTime; 130 private long mElapsedRealtime; 131 132 private static final int UID_A = android.os.Process.FIRST_APPLICATION_UID + 800; 133 private static final int UID_B = android.os.Process.FIRST_APPLICATION_UID + 801; 134 135 private static final int PID_1 = 400; 136 private static final int PID_2 = 401; 137 private static final int PID_3 = 402; 138 139 @Override 140 public void setUp() throws Exception { 141 super.setUp(); 142 143 setCurrentTimeMillis(TEST_START); 144 145 // intercept various broadcasts, and pretend that uids have packages 146 mServiceContext = new BroadcastInterceptingContext(getContext()) { 147 @Override 148 public PackageManager getPackageManager() { 149 return new MockPackageManager() { 150 @Override 151 public String[] getPackagesForUid(int uid) { 152 return new String[] { "com.example" }; 153 } 154 155 @Override 156 public PackageInfo getPackageInfo(String packageName, int flags) { 157 final PackageInfo info = new PackageInfo(); 158 final Signature signature; 159 if ("android".equals(packageName)) { 160 signature = new Signature("F00D"); 161 } else { 162 signature = new Signature("DEAD"); 163 } 164 info.signatures = new Signature[] { signature }; 165 return info; 166 } 167 }; 168 } 169 170 @Override 171 public void startActivity(Intent intent) { 172 // ignored 173 } 174 }; 175 176 mPolicyDir = getContext().getFilesDir(); 177 if (mPolicyDir.exists()) { 178 IoUtils.deleteContents(mPolicyDir); 179 } 180 181 mActivityManager = createMock(IActivityManager.class); 182 mPowerManager = createMock(IPowerManager.class); 183 mStatsService = createMock(INetworkStatsService.class); 184 mNetworkManager = createMock(INetworkManagementService.class); 185 mPolicyListener = createMock(INetworkPolicyListener.class); 186 mTime = createMock(TrustedTime.class); 187 mConnManager = createMock(IConnectivityManager.class); 188 mNotifManager = createMock(INotificationManager.class); 189 190 mService = new NetworkPolicyManagerService(mServiceContext, mActivityManager, mPowerManager, 191 mStatsService, mNetworkManager, mTime, mPolicyDir, true); 192 mService.bindConnectivityManager(mConnManager); 193 mService.bindNotificationManager(mNotifManager); 194 195 // RemoteCallbackList needs a binder to use as key 196 expect(mPolicyListener.asBinder()).andReturn(mStubBinder).atLeastOnce(); 197 replay(); 198 mService.registerListener(mPolicyListener); 199 verifyAndReset(); 200 201 // catch IProcessObserver during systemReady() 202 final Capture<IProcessObserver> processObserver = new Capture<IProcessObserver>(); 203 mActivityManager.registerProcessObserver(capture(processObserver)); 204 expectLastCall().atLeastOnce(); 205 206 // catch INetworkManagementEventObserver during systemReady() 207 final Capture<INetworkManagementEventObserver> networkObserver = new Capture< 208 INetworkManagementEventObserver>(); 209 mNetworkManager.registerObserver(capture(networkObserver)); 210 expectLastCall().atLeastOnce(); 211 212 // expect to answer screen status during systemReady() 213 expect(mPowerManager.isScreenOn()).andReturn(true).atLeastOnce(); 214 expectCurrentTime(); 215 216 replay(); 217 mService.systemReady(); 218 verifyAndReset(); 219 220 mProcessObserver = processObserver.getValue(); 221 mNetworkObserver = networkObserver.getValue(); 222 223 } 224 225 @Override 226 public void tearDown() throws Exception { 227 for (File file : mPolicyDir.listFiles()) { 228 file.delete(); 229 } 230 231 mServiceContext = null; 232 mPolicyDir = null; 233 234 mActivityManager = null; 235 mPowerManager = null; 236 mStatsService = null; 237 mPolicyListener = null; 238 mTime = null; 239 240 mService = null; 241 mProcessObserver = null; 242 243 super.tearDown(); 244 } 245 246 @Suppress 247 public void testPolicyChangeTriggersBroadcast() throws Exception { 248 mService.setUidPolicy(UID_A, POLICY_NONE); 249 250 // change background policy and expect broadcast 251 final Future<Intent> backgroundChanged = mServiceContext.nextBroadcastIntent( 252 ConnectivityManager.ACTION_BACKGROUND_DATA_SETTING_CHANGED); 253 254 mService.setUidPolicy(UID_A, POLICY_REJECT_METERED_BACKGROUND); 255 256 backgroundChanged.get(); 257 } 258 259 public void testPidForegroundCombined() throws Exception { 260 // push all uid into background 261 mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, false); 262 mProcessObserver.onForegroundActivitiesChanged(PID_2, UID_A, false); 263 mProcessObserver.onForegroundActivitiesChanged(PID_3, UID_B, false); 264 waitUntilIdle(); 265 assertFalse(mService.isUidForeground(UID_A)); 266 assertFalse(mService.isUidForeground(UID_B)); 267 268 // push one of the shared pids into foreground 269 mProcessObserver.onForegroundActivitiesChanged(PID_2, UID_A, true); 270 waitUntilIdle(); 271 assertTrue(mService.isUidForeground(UID_A)); 272 assertFalse(mService.isUidForeground(UID_B)); 273 274 // and swap another uid into foreground 275 mProcessObserver.onForegroundActivitiesChanged(PID_2, UID_A, false); 276 mProcessObserver.onForegroundActivitiesChanged(PID_3, UID_B, true); 277 waitUntilIdle(); 278 assertFalse(mService.isUidForeground(UID_A)); 279 assertTrue(mService.isUidForeground(UID_B)); 280 281 // push both pid into foreground 282 mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, true); 283 mProcessObserver.onForegroundActivitiesChanged(PID_2, UID_A, true); 284 waitUntilIdle(); 285 assertTrue(mService.isUidForeground(UID_A)); 286 287 // pull one out, should still be foreground 288 mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, false); 289 waitUntilIdle(); 290 assertTrue(mService.isUidForeground(UID_A)); 291 292 // pull final pid out, should now be background 293 mProcessObserver.onForegroundActivitiesChanged(PID_2, UID_A, false); 294 waitUntilIdle(); 295 assertFalse(mService.isUidForeground(UID_A)); 296 } 297 298 public void testScreenChangesRules() throws Exception { 299 Future<Void> future; 300 301 expectSetUidNetworkRules(UID_A, false); 302 expectSetUidForeground(UID_A, true); 303 future = expectRulesChanged(UID_A, RULE_ALLOW_ALL); 304 replay(); 305 mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, true); 306 future.get(); 307 verifyAndReset(); 308 309 // push strict policy for foreground uid, verify ALLOW rule 310 expectSetUidNetworkRules(UID_A, false); 311 expectSetUidForeground(UID_A, true); 312 future = expectRulesChanged(UID_A, RULE_ALLOW_ALL); 313 replay(); 314 mService.setUidPolicy(UID_A, POLICY_REJECT_METERED_BACKGROUND); 315 future.get(); 316 verifyAndReset(); 317 318 // now turn screen off and verify REJECT rule 319 expect(mPowerManager.isScreenOn()).andReturn(false).atLeastOnce(); 320 expectSetUidNetworkRules(UID_A, true); 321 expectSetUidForeground(UID_A, false); 322 future = expectRulesChanged(UID_A, RULE_REJECT_METERED); 323 replay(); 324 mServiceContext.sendBroadcast(new Intent(Intent.ACTION_SCREEN_OFF)); 325 future.get(); 326 verifyAndReset(); 327 328 // and turn screen back on, verify ALLOW rule restored 329 expect(mPowerManager.isScreenOn()).andReturn(true).atLeastOnce(); 330 expectSetUidNetworkRules(UID_A, false); 331 expectSetUidForeground(UID_A, true); 332 future = expectRulesChanged(UID_A, RULE_ALLOW_ALL); 333 replay(); 334 mServiceContext.sendBroadcast(new Intent(Intent.ACTION_SCREEN_ON)); 335 future.get(); 336 verifyAndReset(); 337 } 338 339 public void testPolicyNone() throws Exception { 340 Future<Void> future; 341 342 expectSetUidNetworkRules(UID_A, false); 343 expectSetUidForeground(UID_A, true); 344 future = expectRulesChanged(UID_A, RULE_ALLOW_ALL); 345 replay(); 346 mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, true); 347 future.get(); 348 verifyAndReset(); 349 350 // POLICY_NONE should RULE_ALLOW in foreground 351 expectSetUidNetworkRules(UID_A, false); 352 expectSetUidForeground(UID_A, true); 353 future = expectRulesChanged(UID_A, RULE_ALLOW_ALL); 354 replay(); 355 mService.setUidPolicy(UID_A, POLICY_NONE); 356 future.get(); 357 verifyAndReset(); 358 359 // POLICY_NONE should RULE_ALLOW in background 360 expectSetUidNetworkRules(UID_A, false); 361 expectSetUidForeground(UID_A, false); 362 future = expectRulesChanged(UID_A, RULE_ALLOW_ALL); 363 replay(); 364 mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, false); 365 future.get(); 366 verifyAndReset(); 367 } 368 369 public void testPolicyReject() throws Exception { 370 Future<Void> future; 371 372 // POLICY_REJECT should RULE_ALLOW in background 373 expectSetUidNetworkRules(UID_A, true); 374 expectSetUidForeground(UID_A, false); 375 future = expectRulesChanged(UID_A, RULE_REJECT_METERED); 376 replay(); 377 mService.setUidPolicy(UID_A, POLICY_REJECT_METERED_BACKGROUND); 378 future.get(); 379 verifyAndReset(); 380 381 // POLICY_REJECT should RULE_ALLOW in foreground 382 expectSetUidNetworkRules(UID_A, false); 383 expectSetUidForeground(UID_A, true); 384 future = expectRulesChanged(UID_A, RULE_ALLOW_ALL); 385 replay(); 386 mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, true); 387 future.get(); 388 verifyAndReset(); 389 390 // POLICY_REJECT should RULE_REJECT in background 391 expectSetUidNetworkRules(UID_A, true); 392 expectSetUidForeground(UID_A, false); 393 future = expectRulesChanged(UID_A, RULE_REJECT_METERED); 394 replay(); 395 mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, false); 396 future.get(); 397 verifyAndReset(); 398 } 399 400 public void testPolicyRejectAddRemove() throws Exception { 401 Future<Void> future; 402 403 // POLICY_NONE should have RULE_ALLOW in background 404 expectSetUidNetworkRules(UID_A, false); 405 expectSetUidForeground(UID_A, false); 406 future = expectRulesChanged(UID_A, RULE_ALLOW_ALL); 407 replay(); 408 mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, false); 409 mService.setUidPolicy(UID_A, POLICY_NONE); 410 future.get(); 411 verifyAndReset(); 412 413 // adding POLICY_REJECT should cause RULE_REJECT 414 expectSetUidNetworkRules(UID_A, true); 415 expectSetUidForeground(UID_A, false); 416 future = expectRulesChanged(UID_A, RULE_REJECT_METERED); 417 replay(); 418 mService.setUidPolicy(UID_A, POLICY_REJECT_METERED_BACKGROUND); 419 future.get(); 420 verifyAndReset(); 421 422 // removing POLICY_REJECT should return us to RULE_ALLOW 423 expectSetUidNetworkRules(UID_A, false); 424 expectSetUidForeground(UID_A, false); 425 future = expectRulesChanged(UID_A, RULE_ALLOW_ALL); 426 replay(); 427 mService.setUidPolicy(UID_A, POLICY_NONE); 428 future.get(); 429 verifyAndReset(); 430 } 431 432 public void testLastCycleBoundaryThisMonth() throws Exception { 433 // assume cycle day of "5th", which should be in same month 434 final long currentTime = parseTime("2007-11-14T00:00:00.000Z"); 435 final long expectedCycle = parseTime("2007-11-05T00:00:00.000Z"); 436 437 final NetworkPolicy policy = new NetworkPolicy( 438 sTemplateWifi, 5, 1024L, 1024L, SNOOZE_NEVER); 439 final long actualCycle = computeLastCycleBoundary(currentTime, policy); 440 assertTimeEquals(expectedCycle, actualCycle); 441 } 442 443 public void testLastCycleBoundaryLastMonth() throws Exception { 444 // assume cycle day of "20th", which should be in last month 445 final long currentTime = parseTime("2007-11-14T00:00:00.000Z"); 446 final long expectedCycle = parseTime("2007-10-20T00:00:00.000Z"); 447 448 final NetworkPolicy policy = new NetworkPolicy( 449 sTemplateWifi, 20, 1024L, 1024L, SNOOZE_NEVER); 450 final long actualCycle = computeLastCycleBoundary(currentTime, policy); 451 assertTimeEquals(expectedCycle, actualCycle); 452 } 453 454 public void testLastCycleBoundaryThisMonthFebruary() throws Exception { 455 // assume cycle day of "30th" in february; should go to january 456 final long currentTime = parseTime("2007-02-14T00:00:00.000Z"); 457 final long expectedCycle = parseTime("2007-01-30T00:00:00.000Z"); 458 459 final NetworkPolicy policy = new NetworkPolicy( 460 sTemplateWifi, 30, 1024L, 1024L, SNOOZE_NEVER); 461 final long actualCycle = computeLastCycleBoundary(currentTime, policy); 462 assertTimeEquals(expectedCycle, actualCycle); 463 } 464 465 public void testLastCycleBoundaryLastMonthFebruary() throws Exception { 466 // assume cycle day of "30th" in february, which should clamp 467 final long currentTime = parseTime("2007-03-14T00:00:00.000Z"); 468 final long expectedCycle = parseTime("2007-02-28T23:59:59.000Z"); 469 470 final NetworkPolicy policy = new NetworkPolicy( 471 sTemplateWifi, 30, 1024L, 1024L, SNOOZE_NEVER); 472 final long actualCycle = computeLastCycleBoundary(currentTime, policy); 473 assertTimeEquals(expectedCycle, actualCycle); 474 } 475 476 public void testNextCycleSane() throws Exception { 477 final NetworkPolicy policy = new NetworkPolicy( 478 sTemplateWifi, 31, WARNING_DISABLED, LIMIT_DISABLED, SNOOZE_NEVER); 479 final LinkedHashSet<Long> seen = new LinkedHashSet<Long>(); 480 481 // walk forwards, ensuring that cycle boundaries don't get stuck 482 long currentCycle = computeNextCycleBoundary(parseTime("2011-08-01T00:00:00.000Z"), policy); 483 for (int i = 0; i < 128; i++) { 484 long nextCycle = computeNextCycleBoundary(currentCycle, policy); 485 assertEqualsFuzzy(DAY_IN_MILLIS * 30, nextCycle - currentCycle, DAY_IN_MILLIS * 3); 486 assertUnique(seen, nextCycle); 487 currentCycle = nextCycle; 488 } 489 } 490 491 public void testLastCycleSane() throws Exception { 492 final NetworkPolicy policy = new NetworkPolicy( 493 sTemplateWifi, 31, WARNING_DISABLED, LIMIT_DISABLED, SNOOZE_NEVER); 494 final LinkedHashSet<Long> seen = new LinkedHashSet<Long>(); 495 496 // walk backwards, ensuring that cycle boundaries look sane 497 long currentCycle = computeLastCycleBoundary(parseTime("2011-08-04T00:00:00.000Z"), policy); 498 for (int i = 0; i < 128; i++) { 499 long lastCycle = computeLastCycleBoundary(currentCycle, policy); 500 assertEqualsFuzzy(DAY_IN_MILLIS * 30, currentCycle - lastCycle, DAY_IN_MILLIS * 3); 501 assertUnique(seen, lastCycle); 502 currentCycle = lastCycle; 503 } 504 } 505 506 public void testNetworkPolicyAppliedCycleLastMonth() throws Exception { 507 NetworkState[] state = null; 508 NetworkStats stats = null; 509 Future<Void> future; 510 511 final long TIME_FEB_15 = 1171497600000L; 512 final long TIME_MAR_10 = 1173484800000L; 513 final int CYCLE_DAY = 15; 514 515 setCurrentTimeMillis(TIME_MAR_10); 516 517 // first, pretend that wifi network comes online. no policy active, 518 // which means we shouldn't push limit to interface. 519 state = new NetworkState[] { buildWifi() }; 520 expect(mConnManager.getAllNetworkState()).andReturn(state).atLeastOnce(); 521 expectCurrentTime(); 522 expectClearNotifications(); 523 future = expectMeteredIfacesChanged(); 524 525 replay(); 526 mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE)); 527 future.get(); 528 verifyAndReset(); 529 530 // now change cycle to be on 15th, and test in early march, to verify we 531 // pick cycle day in previous month. 532 expect(mConnManager.getAllNetworkState()).andReturn(state).atLeastOnce(); 533 expectCurrentTime(); 534 535 // pretend that 512 bytes total have happened 536 stats = new NetworkStats(getElapsedRealtime(), 1) 537 .addIfaceValues(TEST_IFACE, 256L, 2L, 256L, 2L); 538 expect(mStatsService.getSummaryForNetwork(sTemplateWifi, TIME_FEB_15, TIME_MAR_10)) 539 .andReturn(stats).atLeastOnce(); 540 541 // TODO: consider making strongly ordered mock 542 expectRemoveInterfaceQuota(TEST_IFACE); 543 expectSetInterfaceQuota(TEST_IFACE, (2 * MB_IN_BYTES) - 512); 544 545 expectClearNotifications(); 546 future = expectMeteredIfacesChanged(TEST_IFACE); 547 548 replay(); 549 setNetworkPolicies(new NetworkPolicy( 550 sTemplateWifi, CYCLE_DAY, 1 * MB_IN_BYTES, 2 * MB_IN_BYTES, SNOOZE_NEVER)); 551 future.get(); 552 verifyAndReset(); 553 } 554 555 public void testUidRemovedPolicyCleared() throws Exception { 556 Future<Void> future; 557 558 // POLICY_REJECT should RULE_REJECT in background 559 expectSetUidNetworkRules(UID_A, true); 560 expectSetUidForeground(UID_A, false); 561 future = expectRulesChanged(UID_A, RULE_REJECT_METERED); 562 replay(); 563 mService.setUidPolicy(UID_A, POLICY_REJECT_METERED_BACKGROUND); 564 future.get(); 565 verifyAndReset(); 566 567 // uninstall should clear RULE_REJECT 568 expectSetUidNetworkRules(UID_A, false); 569 expectSetUidForeground(UID_A, false); 570 future = expectRulesChanged(UID_A, RULE_ALLOW_ALL); 571 replay(); 572 final Intent intent = new Intent(ACTION_UID_REMOVED); 573 intent.putExtra(EXTRA_UID, UID_A); 574 mServiceContext.sendBroadcast(intent); 575 future.get(); 576 verifyAndReset(); 577 } 578 579 public void testOverWarningLimitNotification() throws Exception { 580 NetworkState[] state = null; 581 NetworkStats stats = null; 582 Future<Void> future; 583 Capture<String> tag; 584 585 final long TIME_FEB_15 = 1171497600000L; 586 final long TIME_MAR_10 = 1173484800000L; 587 final int CYCLE_DAY = 15; 588 589 setCurrentTimeMillis(TIME_MAR_10); 590 591 // assign wifi policy 592 state = new NetworkState[] {}; 593 stats = new NetworkStats(getElapsedRealtime(), 1) 594 .addIfaceValues(TEST_IFACE, 0L, 0L, 0L, 0L); 595 596 { 597 expectCurrentTime(); 598 expect(mConnManager.getAllNetworkState()).andReturn(state).atLeastOnce(); 599 expect(mStatsService.getSummaryForNetwork(sTemplateWifi, TIME_FEB_15, currentTimeMillis())) 600 .andReturn(stats).atLeastOnce(); 601 602 expectClearNotifications(); 603 future = expectMeteredIfacesChanged(); 604 605 replay(); 606 setNetworkPolicies(new NetworkPolicy( 607 sTemplateWifi, CYCLE_DAY, 1 * MB_IN_BYTES, 2 * MB_IN_BYTES, SNOOZE_NEVER)); 608 future.get(); 609 verifyAndReset(); 610 } 611 612 // bring up wifi network 613 incrementCurrentTime(MINUTE_IN_MILLIS); 614 state = new NetworkState[] { buildWifi() }; 615 stats = new NetworkStats(getElapsedRealtime(), 1) 616 .addIfaceValues(TEST_IFACE, 0L, 0L, 0L, 0L); 617 618 { 619 expectCurrentTime(); 620 expect(mConnManager.getAllNetworkState()).andReturn(state).atLeastOnce(); 621 expect(mStatsService.getSummaryForNetwork(sTemplateWifi, TIME_FEB_15, currentTimeMillis())) 622 .andReturn(stats).atLeastOnce(); 623 624 expectRemoveInterfaceQuota(TEST_IFACE); 625 expectSetInterfaceQuota(TEST_IFACE, 2 * MB_IN_BYTES); 626 627 expectClearNotifications(); 628 future = expectMeteredIfacesChanged(TEST_IFACE); 629 630 replay(); 631 mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE)); 632 future.get(); 633 verifyAndReset(); 634 } 635 636 // go over warning, which should kick notification 637 incrementCurrentTime(MINUTE_IN_MILLIS); 638 stats = new NetworkStats(getElapsedRealtime(), 1) 639 .addIfaceValues(TEST_IFACE, 1536 * KB_IN_BYTES, 15L, 0L, 0L); 640 641 { 642 expectCurrentTime(); 643 expect(mStatsService.getSummaryForNetwork(sTemplateWifi, TIME_FEB_15, currentTimeMillis())) 644 .andReturn(stats).atLeastOnce(); 645 646 expectForceUpdate(); 647 expectClearNotifications(); 648 tag = expectEnqueueNotification(); 649 650 replay(); 651 mNetworkObserver.limitReached(null, TEST_IFACE); 652 assertNotificationType(TYPE_WARNING, tag.getValue()); 653 verifyAndReset(); 654 } 655 656 // go over limit, which should kick notification and dialog 657 incrementCurrentTime(MINUTE_IN_MILLIS); 658 stats = new NetworkStats(getElapsedRealtime(), 1) 659 .addIfaceValues(TEST_IFACE, 5 * MB_IN_BYTES, 512L, 0L, 0L); 660 661 { 662 expectCurrentTime(); 663 expect(mStatsService.getSummaryForNetwork(sTemplateWifi, TIME_FEB_15, currentTimeMillis())) 664 .andReturn(stats).atLeastOnce(); 665 expectPolicyDataEnable(TYPE_WIFI, false).atLeastOnce(); 666 667 expectForceUpdate(); 668 expectClearNotifications(); 669 tag = expectEnqueueNotification(); 670 671 replay(); 672 mNetworkObserver.limitReached(null, TEST_IFACE); 673 assertNotificationType(TYPE_LIMIT, tag.getValue()); 674 verifyAndReset(); 675 } 676 677 // now snooze policy, which should remove quota 678 incrementCurrentTime(MINUTE_IN_MILLIS); 679 680 { 681 expectCurrentTime(); 682 expect(mConnManager.getAllNetworkState()).andReturn(state).atLeastOnce(); 683 expect(mStatsService.getSummaryForNetwork(sTemplateWifi, TIME_FEB_15, currentTimeMillis())) 684 .andReturn(stats).atLeastOnce(); 685 expectPolicyDataEnable(TYPE_WIFI, true).atLeastOnce(); 686 687 // snoozed interface still has high quota so background data is 688 // still restricted. 689 expectRemoveInterfaceQuota(TEST_IFACE); 690 expectSetInterfaceQuota(TEST_IFACE, Long.MAX_VALUE); 691 692 expectClearNotifications(); 693 tag = expectEnqueueNotification(); 694 future = expectMeteredIfacesChanged(TEST_IFACE); 695 696 replay(); 697 mService.snoozePolicy(sTemplateWifi); 698 future.get(); 699 assertNotificationType(TYPE_LIMIT_SNOOZED, tag.getValue()); 700 verifyAndReset(); 701 } 702 } 703 704 private static long parseTime(String time) { 705 final Time result = new Time(); 706 result.parse3339(time); 707 return result.toMillis(true); 708 } 709 710 private void setNetworkPolicies(NetworkPolicy... policies) { 711 mService.setNetworkPolicies(policies); 712 } 713 714 private static NetworkState buildWifi() { 715 final NetworkInfo info = new NetworkInfo(TYPE_WIFI, 0, null, null); 716 info.setDetailedState(DetailedState.CONNECTED, null, null); 717 final LinkProperties prop = new LinkProperties(); 718 prop.setInterfaceName(TEST_IFACE); 719 return new NetworkState(info, prop, null); 720 } 721 722 private void expectCurrentTime() throws Exception { 723 expect(mTime.forceRefresh()).andReturn(false).anyTimes(); 724 expect(mTime.hasCache()).andReturn(true).anyTimes(); 725 expect(mTime.currentTimeMillis()).andReturn(currentTimeMillis()).anyTimes(); 726 expect(mTime.getCacheAge()).andReturn(0L).anyTimes(); 727 expect(mTime.getCacheCertainty()).andReturn(0L).anyTimes(); 728 } 729 730 private void expectForceUpdate() throws Exception { 731 mStatsService.forceUpdate(); 732 expectLastCall().atLeastOnce(); 733 } 734 735 private void expectClearNotifications() throws Exception { 736 mNotifManager.cancelNotificationWithTag(isA(String.class), isA(String.class), anyInt()); 737 expectLastCall().anyTimes(); 738 } 739 740 private Capture<String> expectEnqueueNotification() throws Exception { 741 final Capture<String> tag = new Capture<String>(); 742 mNotifManager.enqueueNotificationWithTag(isA(String.class), capture(tag), anyInt(), 743 isA(Notification.class), isA(int[].class)); 744 return tag; 745 } 746 747 private void expectSetInterfaceQuota(String iface, long quotaBytes) throws Exception { 748 mNetworkManager.setInterfaceQuota(iface, quotaBytes); 749 expectLastCall().atLeastOnce(); 750 } 751 752 private void expectRemoveInterfaceQuota(String iface) throws Exception { 753 mNetworkManager.removeInterfaceQuota(iface); 754 expectLastCall().atLeastOnce(); 755 } 756 757 private void expectSetInterfaceAlert(String iface, long alertBytes) throws Exception { 758 mNetworkManager.setInterfaceAlert(iface, alertBytes); 759 expectLastCall().atLeastOnce(); 760 } 761 762 private void expectRemoveInterfaceAlert(String iface) throws Exception { 763 mNetworkManager.removeInterfaceAlert(iface); 764 expectLastCall().atLeastOnce(); 765 } 766 767 private void expectSetUidNetworkRules(int uid, boolean rejectOnQuotaInterfaces) 768 throws Exception { 769 mNetworkManager.setUidNetworkRules(uid, rejectOnQuotaInterfaces); 770 expectLastCall().atLeastOnce(); 771 } 772 773 private void expectSetUidForeground(int uid, boolean uidForeground) throws Exception { 774 mStatsService.setUidForeground(uid, uidForeground); 775 expectLastCall().atLeastOnce(); 776 } 777 778 private Future<Void> expectRulesChanged(int uid, int policy) throws Exception { 779 final FutureAnswer future = new FutureAnswer(); 780 mPolicyListener.onUidRulesChanged(eq(uid), eq(policy)); 781 expectLastCall().andAnswer(future); 782 return future; 783 } 784 785 private Future<Void> expectMeteredIfacesChanged(String... ifaces) throws Exception { 786 final FutureAnswer future = new FutureAnswer(); 787 mPolicyListener.onMeteredIfacesChanged(aryEq(ifaces)); 788 expectLastCall().andAnswer(future); 789 return future; 790 } 791 792 private <T> IExpectationSetters<T> expectPolicyDataEnable(int type, boolean enabled) 793 throws Exception { 794 mConnManager.setPolicyDataEnable(type, enabled); 795 return expectLastCall(); 796 } 797 798 private static class FutureAnswer extends AbstractFuture<Void> implements IAnswer<Void> { 799 @Override 800 public Void get() throws InterruptedException, ExecutionException { 801 try { 802 return get(5, TimeUnit.SECONDS); 803 } catch (TimeoutException e) { 804 throw new RuntimeException(e); 805 } 806 } 807 808 @Override 809 public Void answer() { 810 set(null); 811 return null; 812 } 813 } 814 815 private static class IdleFuture extends AbstractFuture<Void> implements IdleHandler { 816 @Override 817 public Void get() throws InterruptedException, ExecutionException { 818 try { 819 return get(5, TimeUnit.SECONDS); 820 } catch (TimeoutException e) { 821 throw new RuntimeException(e); 822 } 823 } 824 825 /** {@inheritDoc} */ 826 public boolean queueIdle() { 827 set(null); 828 return false; 829 } 830 } 831 832 /** 833 * Wait until {@link #mService} internal {@link Handler} is idle. 834 */ 835 private void waitUntilIdle() throws Exception { 836 final IdleFuture future = new IdleFuture(); 837 mService.addIdleHandler(future); 838 future.get(); 839 } 840 841 private static void assertTimeEquals(long expected, long actual) { 842 if (expected != actual) { 843 fail("expected " + formatTime(expected) + " but was actually " + formatTime(actual)); 844 } 845 } 846 847 private static String formatTime(long millis) { 848 final Time time = new Time(Time.TIMEZONE_UTC); 849 time.set(millis); 850 return time.format3339(false); 851 } 852 853 private static void assertEqualsFuzzy(long expected, long actual, long fuzzy) { 854 final long low = expected - fuzzy; 855 final long high = expected + fuzzy; 856 if (actual < low || actual > high) { 857 fail("value " + actual + " is outside [" + low + "," + high + "]"); 858 } 859 } 860 861 private static void assertUnique(LinkedHashSet<Long> seen, Long value) { 862 if (!seen.add(value)) { 863 fail("found duplicate time " + value + " in series " + seen.toString()); 864 } 865 } 866 867 private static void assertNotificationType(int expected, String actualTag) { 868 assertEquals( 869 Integer.toString(expected), actualTag.substring(actualTag.lastIndexOf(':') + 1)); 870 } 871 872 private long getElapsedRealtime() { 873 return mElapsedRealtime; 874 } 875 876 private void setCurrentTimeMillis(long currentTimeMillis) { 877 mStartTime = currentTimeMillis; 878 mElapsedRealtime = 0L; 879 } 880 881 private long currentTimeMillis() { 882 return mStartTime + mElapsedRealtime; 883 } 884 885 private void incrementCurrentTime(long duration) { 886 mElapsedRealtime += duration; 887 } 888 889 private void replay() { 890 EasyMock.replay(mActivityManager, mPowerManager, mStatsService, mPolicyListener, 891 mNetworkManager, mTime, mConnManager, mNotifManager); 892 } 893 894 private void verifyAndReset() { 895 EasyMock.verify(mActivityManager, mPowerManager, mStatsService, mPolicyListener, 896 mNetworkManager, mTime, mConnManager, mNotifManager); 897 EasyMock.reset(mActivityManager, mPowerManager, mStatsService, mPolicyListener, 898 mNetworkManager, mTime, mConnManager, mNotifManager); 899 } 900} 901