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