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