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