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