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