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