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.anyLong; 41import static org.easymock.EasyMock.aryEq; 42import static org.easymock.EasyMock.capture; 43import static org.easymock.EasyMock.createMock; 44import static org.easymock.EasyMock.eq; 45import static org.easymock.EasyMock.expect; 46import static org.easymock.EasyMock.expectLastCall; 47import static org.easymock.EasyMock.isA; 48 49import android.app.IActivityManager; 50import android.app.INotificationManager; 51import android.app.IProcessObserver; 52import android.app.Notification; 53import android.content.Intent; 54import android.content.pm.PackageInfo; 55import android.content.pm.PackageManager; 56import android.content.pm.Signature; 57import android.net.ConnectivityManager; 58import android.net.IConnectivityManager; 59import android.net.INetworkManagementEventObserver; 60import android.net.INetworkPolicyListener; 61import android.net.INetworkStatsService; 62import android.net.LinkProperties; 63import android.net.NetworkInfo; 64import android.net.NetworkInfo.DetailedState; 65import android.net.NetworkPolicy; 66import android.net.NetworkState; 67import android.net.NetworkStats; 68import android.net.NetworkTemplate; 69import android.os.Binder; 70import android.os.INetworkManagementService; 71import android.os.IPowerManager; 72import android.os.MessageQueue.IdleHandler; 73import android.os.UserHandle; 74import android.test.AndroidTestCase; 75import android.test.mock.MockPackageManager; 76import android.test.suitebuilder.annotation.LargeTest; 77import android.test.suitebuilder.annotation.Suppress; 78import android.text.format.Time; 79import android.util.TrustedTime; 80 81import com.android.server.net.NetworkPolicyManagerService; 82import com.google.common.util.concurrent.AbstractFuture; 83 84import org.easymock.Capture; 85import org.easymock.EasyMock; 86import org.easymock.IAnswer; 87 88import java.io.File; 89import java.util.LinkedHashSet; 90import java.util.concurrent.ExecutionException; 91import java.util.concurrent.Future; 92import java.util.concurrent.TimeUnit; 93import java.util.concurrent.TimeoutException; 94import java.util.logging.Handler; 95 96import libcore.io.IoUtils; 97 98/** 99 * Tests for {@link NetworkPolicyManagerService}. 100 */ 101@LargeTest 102public 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.isInteractive()).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.isInteractive()).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.isInteractive()).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 testCycleTodayJanuary() throws Exception { 561 final NetworkPolicy policy = new NetworkPolicy( 562 sTemplateWifi, 14, "US/Pacific", 1024L, 1024L, false); 563 564 assertTimeEquals(parseTime("2013-01-14T00:00:00.000-08:00"), 565 computeNextCycleBoundary(parseTime("2013-01-13T23:59:59.000-08:00"), policy)); 566 assertTimeEquals(parseTime("2013-02-14T00:00:00.000-08:00"), 567 computeNextCycleBoundary(parseTime("2013-01-14T00:00:01.000-08:00"), policy)); 568 assertTimeEquals(parseTime("2013-02-14T00:00:00.000-08:00"), 569 computeNextCycleBoundary(parseTime("2013-01-14T15:11:00.000-08:00"), policy)); 570 571 assertTimeEquals(parseTime("2012-12-14T00:00:00.000-08:00"), 572 computeLastCycleBoundary(parseTime("2013-01-13T23:59:59.000-08:00"), policy)); 573 assertTimeEquals(parseTime("2013-01-14T00:00:00.000-08:00"), 574 computeLastCycleBoundary(parseTime("2013-01-14T00:00:01.000-08:00"), policy)); 575 assertTimeEquals(parseTime("2013-01-14T00:00:00.000-08:00"), 576 computeLastCycleBoundary(parseTime("2013-01-14T15:11:00.000-08:00"), policy)); 577 } 578 579 public void testNetworkPolicyAppliedCycleLastMonth() throws Exception { 580 NetworkState[] state = null; 581 NetworkStats stats = null; 582 Future<Void> future; 583 584 final long TIME_FEB_15 = 1171497600000L; 585 final long TIME_MAR_10 = 1173484800000L; 586 final int CYCLE_DAY = 15; 587 588 setCurrentTimeMillis(TIME_MAR_10); 589 590 // first, pretend that wifi network comes online. no policy active, 591 // which means we shouldn't push limit to interface. 592 state = new NetworkState[] { buildWifi() }; 593 expect(mConnManager.getAllNetworkState()).andReturn(state).atLeastOnce(); 594 expectCurrentTime(); 595 expectClearNotifications(); 596 expectAdvisePersistThreshold(); 597 future = expectMeteredIfacesChanged(); 598 599 replay(); 600 mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE)); 601 future.get(); 602 verifyAndReset(); 603 604 // now change cycle to be on 15th, and test in early march, to verify we 605 // pick cycle day in previous month. 606 expect(mConnManager.getAllNetworkState()).andReturn(state).atLeastOnce(); 607 expectCurrentTime(); 608 609 // pretend that 512 bytes total have happened 610 stats = new NetworkStats(getElapsedRealtime(), 1) 611 .addIfaceValues(TEST_IFACE, 256L, 2L, 256L, 2L); 612 expect(mStatsService.getNetworkTotalBytes(sTemplateWifi, TIME_FEB_15, TIME_MAR_10)) 613 .andReturn(stats.getTotalBytes()).atLeastOnce(); 614 expectPolicyDataEnable(TYPE_WIFI, true); 615 616 // TODO: consider making strongly ordered mock 617 expectRemoveInterfaceQuota(TEST_IFACE); 618 expectSetInterfaceQuota(TEST_IFACE, (2 * MB_IN_BYTES) - 512); 619 620 expectClearNotifications(); 621 expectAdvisePersistThreshold(); 622 future = expectMeteredIfacesChanged(TEST_IFACE); 623 624 replay(); 625 setNetworkPolicies(new NetworkPolicy( 626 sTemplateWifi, CYCLE_DAY, TIMEZONE_UTC, 1 * MB_IN_BYTES, 2 * MB_IN_BYTES, false)); 627 future.get(); 628 verifyAndReset(); 629 } 630 631 public void testUidRemovedPolicyCleared() throws Exception { 632 Future<Void> future; 633 634 // POLICY_REJECT should RULE_REJECT in background 635 expectSetUidNetworkRules(UID_A, true); 636 expectSetUidForeground(UID_A, false); 637 future = expectRulesChanged(UID_A, RULE_REJECT_METERED); 638 replay(); 639 mService.setUidPolicy(APP_ID_A, POLICY_REJECT_METERED_BACKGROUND); 640 future.get(); 641 verifyAndReset(); 642 643 // uninstall should clear RULE_REJECT 644 expectSetUidNetworkRules(UID_A, false); 645 expectSetUidForeground(UID_A, false); 646 future = expectRulesChanged(UID_A, RULE_ALLOW_ALL); 647 replay(); 648 final Intent intent = new Intent(ACTION_UID_REMOVED); 649 intent.putExtra(EXTRA_UID, UID_A); 650 mServiceContext.sendBroadcast(intent); 651 future.get(); 652 verifyAndReset(); 653 } 654 655 public void testOverWarningLimitNotification() throws Exception { 656 NetworkState[] state = null; 657 NetworkStats stats = null; 658 Future<Void> future; 659 Future<String> tagFuture; 660 661 final long TIME_FEB_15 = 1171497600000L; 662 final long TIME_MAR_10 = 1173484800000L; 663 final int CYCLE_DAY = 15; 664 665 setCurrentTimeMillis(TIME_MAR_10); 666 667 // assign wifi policy 668 state = new NetworkState[] {}; 669 stats = new NetworkStats(getElapsedRealtime(), 1) 670 .addIfaceValues(TEST_IFACE, 0L, 0L, 0L, 0L); 671 672 { 673 expectCurrentTime(); 674 expect(mConnManager.getAllNetworkState()).andReturn(state).atLeastOnce(); 675 expect(mStatsService.getNetworkTotalBytes(sTemplateWifi, TIME_FEB_15, currentTimeMillis())) 676 .andReturn(stats.getTotalBytes()).atLeastOnce(); 677 expectPolicyDataEnable(TYPE_WIFI, true); 678 679 expectClearNotifications(); 680 expectAdvisePersistThreshold(); 681 future = expectMeteredIfacesChanged(); 682 683 replay(); 684 setNetworkPolicies(new NetworkPolicy(sTemplateWifi, CYCLE_DAY, TIMEZONE_UTC, 1 685 * MB_IN_BYTES, 2 * MB_IN_BYTES, false)); 686 future.get(); 687 verifyAndReset(); 688 } 689 690 // bring up wifi network 691 incrementCurrentTime(MINUTE_IN_MILLIS); 692 state = new NetworkState[] { buildWifi() }; 693 stats = new NetworkStats(getElapsedRealtime(), 1) 694 .addIfaceValues(TEST_IFACE, 0L, 0L, 0L, 0L); 695 696 { 697 expectCurrentTime(); 698 expect(mConnManager.getAllNetworkState()).andReturn(state).atLeastOnce(); 699 expect(mStatsService.getNetworkTotalBytes(sTemplateWifi, TIME_FEB_15, currentTimeMillis())) 700 .andReturn(stats.getTotalBytes()).atLeastOnce(); 701 expectPolicyDataEnable(TYPE_WIFI, true); 702 703 expectRemoveInterfaceQuota(TEST_IFACE); 704 expectSetInterfaceQuota(TEST_IFACE, 2 * MB_IN_BYTES); 705 706 expectClearNotifications(); 707 expectAdvisePersistThreshold(); 708 future = expectMeteredIfacesChanged(TEST_IFACE); 709 710 replay(); 711 mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE)); 712 future.get(); 713 verifyAndReset(); 714 } 715 716 // go over warning, which should kick notification 717 incrementCurrentTime(MINUTE_IN_MILLIS); 718 stats = new NetworkStats(getElapsedRealtime(), 1) 719 .addIfaceValues(TEST_IFACE, 1536 * KB_IN_BYTES, 15L, 0L, 0L); 720 721 { 722 expectCurrentTime(); 723 expect(mStatsService.getNetworkTotalBytes(sTemplateWifi, TIME_FEB_15, currentTimeMillis())) 724 .andReturn(stats.getTotalBytes()).atLeastOnce(); 725 expectPolicyDataEnable(TYPE_WIFI, true); 726 727 expectForceUpdate(); 728 expectClearNotifications(); 729 tagFuture = expectEnqueueNotification(); 730 731 replay(); 732 mNetworkObserver.limitReached(null, TEST_IFACE); 733 assertNotificationType(TYPE_WARNING, tagFuture.get()); 734 verifyAndReset(); 735 } 736 737 // go over limit, which should kick notification and dialog 738 incrementCurrentTime(MINUTE_IN_MILLIS); 739 stats = new NetworkStats(getElapsedRealtime(), 1) 740 .addIfaceValues(TEST_IFACE, 5 * MB_IN_BYTES, 512L, 0L, 0L); 741 742 { 743 expectCurrentTime(); 744 expect(mStatsService.getNetworkTotalBytes(sTemplateWifi, TIME_FEB_15, currentTimeMillis())) 745 .andReturn(stats.getTotalBytes()).atLeastOnce(); 746 expectPolicyDataEnable(TYPE_WIFI, false); 747 748 expectForceUpdate(); 749 expectClearNotifications(); 750 tagFuture = expectEnqueueNotification(); 751 752 replay(); 753 mNetworkObserver.limitReached(null, TEST_IFACE); 754 assertNotificationType(TYPE_LIMIT, tagFuture.get()); 755 verifyAndReset(); 756 } 757 758 // now snooze policy, which should remove quota 759 incrementCurrentTime(MINUTE_IN_MILLIS); 760 761 { 762 expectCurrentTime(); 763 expect(mConnManager.getAllNetworkState()).andReturn(state).atLeastOnce(); 764 expect(mStatsService.getNetworkTotalBytes(sTemplateWifi, TIME_FEB_15, currentTimeMillis())) 765 .andReturn(stats.getTotalBytes()).atLeastOnce(); 766 expectPolicyDataEnable(TYPE_WIFI, true); 767 768 // snoozed interface still has high quota so background data is 769 // still restricted. 770 expectRemoveInterfaceQuota(TEST_IFACE); 771 expectSetInterfaceQuota(TEST_IFACE, Long.MAX_VALUE); 772 expectAdvisePersistThreshold(); 773 expectMeteredIfacesChanged(TEST_IFACE); 774 775 future = expectClearNotifications(); 776 tagFuture = expectEnqueueNotification(); 777 778 replay(); 779 mService.snoozeLimit(sTemplateWifi); 780 assertNotificationType(TYPE_LIMIT_SNOOZED, tagFuture.get()); 781 future.get(); 782 verifyAndReset(); 783 } 784 } 785 786 public void testMeteredNetworkWithoutLimit() throws Exception { 787 NetworkState[] state = null; 788 NetworkStats stats = null; 789 Future<Void> future; 790 Future<String> tagFuture; 791 792 final long TIME_FEB_15 = 1171497600000L; 793 final long TIME_MAR_10 = 1173484800000L; 794 final int CYCLE_DAY = 15; 795 796 setCurrentTimeMillis(TIME_MAR_10); 797 798 // bring up wifi network with metered policy 799 state = new NetworkState[] { buildWifi() }; 800 stats = new NetworkStats(getElapsedRealtime(), 1) 801 .addIfaceValues(TEST_IFACE, 0L, 0L, 0L, 0L); 802 803 { 804 expectCurrentTime(); 805 expect(mConnManager.getAllNetworkState()).andReturn(state).atLeastOnce(); 806 expect(mStatsService.getNetworkTotalBytes(sTemplateWifi, TIME_FEB_15, currentTimeMillis())) 807 .andReturn(stats.getTotalBytes()).atLeastOnce(); 808 expectPolicyDataEnable(TYPE_WIFI, true); 809 810 expectRemoveInterfaceQuota(TEST_IFACE); 811 expectSetInterfaceQuota(TEST_IFACE, Long.MAX_VALUE); 812 813 expectClearNotifications(); 814 expectAdvisePersistThreshold(); 815 future = expectMeteredIfacesChanged(TEST_IFACE); 816 817 replay(); 818 setNetworkPolicies(new NetworkPolicy( 819 sTemplateWifi, CYCLE_DAY, TIMEZONE_UTC, WARNING_DISABLED, LIMIT_DISABLED, 820 true)); 821 future.get(); 822 verifyAndReset(); 823 } 824 } 825 826 private static long parseTime(String time) { 827 final Time result = new Time(); 828 result.parse3339(time); 829 return result.toMillis(true); 830 } 831 832 private void setNetworkPolicies(NetworkPolicy... policies) { 833 mService.setNetworkPolicies(policies); 834 } 835 836 private static NetworkState buildWifi() { 837 final NetworkInfo info = new NetworkInfo(TYPE_WIFI, 0, null, null); 838 info.setDetailedState(DetailedState.CONNECTED, null, null); 839 final LinkProperties prop = new LinkProperties(); 840 prop.setInterfaceName(TEST_IFACE); 841 return new NetworkState(info, prop, null, null, null, TEST_SSID); 842 } 843 844 private void expectCurrentTime() throws Exception { 845 expect(mTime.forceRefresh()).andReturn(false).anyTimes(); 846 expect(mTime.hasCache()).andReturn(true).anyTimes(); 847 expect(mTime.currentTimeMillis()).andReturn(currentTimeMillis()).anyTimes(); 848 expect(mTime.getCacheAge()).andReturn(0L).anyTimes(); 849 expect(mTime.getCacheCertainty()).andReturn(0L).anyTimes(); 850 } 851 852 private void expectForceUpdate() throws Exception { 853 mStatsService.forceUpdate(); 854 expectLastCall().atLeastOnce(); 855 } 856 857 private Future<Void> expectClearNotifications() throws Exception { 858 final FutureAnswer future = new FutureAnswer(); 859 mNotifManager.cancelNotificationWithTag( 860 isA(String.class), isA(String.class), anyInt(), anyInt()); 861 expectLastCall().andAnswer(future).anyTimes(); 862 return future; 863 } 864 865 private Future<String> expectEnqueueNotification() throws Exception { 866 final FutureCapture<String> tag = new FutureCapture<String>(); 867 mNotifManager.enqueueNotificationWithTag(isA(String.class), isA(String.class), 868 capture(tag.capture), anyInt(), 869 isA(Notification.class), isA(int[].class), UserHandle.myUserId()); 870 return tag; 871 } 872 873 private void expectSetInterfaceQuota(String iface, long quotaBytes) throws Exception { 874 mNetworkManager.setInterfaceQuota(iface, quotaBytes); 875 expectLastCall().atLeastOnce(); 876 } 877 878 private void expectRemoveInterfaceQuota(String iface) throws Exception { 879 mNetworkManager.removeInterfaceQuota(iface); 880 expectLastCall().atLeastOnce(); 881 } 882 883 private void expectSetInterfaceAlert(String iface, long alertBytes) throws Exception { 884 mNetworkManager.setInterfaceAlert(iface, alertBytes); 885 expectLastCall().atLeastOnce(); 886 } 887 888 private void expectRemoveInterfaceAlert(String iface) throws Exception { 889 mNetworkManager.removeInterfaceAlert(iface); 890 expectLastCall().atLeastOnce(); 891 } 892 893 private void expectSetUidNetworkRules(int uid, boolean rejectOnQuotaInterfaces) 894 throws Exception { 895 mNetworkManager.setUidNetworkRules(uid, rejectOnQuotaInterfaces); 896 expectLastCall().atLeastOnce(); 897 } 898 899 private void expectSetUidForeground(int uid, boolean uidForeground) throws Exception { 900 mStatsService.setUidForeground(uid, uidForeground); 901 expectLastCall().atLeastOnce(); 902 } 903 904 private Future<Void> expectRulesChanged(int uid, int policy) throws Exception { 905 final FutureAnswer future = new FutureAnswer(); 906 mPolicyListener.onUidRulesChanged(eq(uid), eq(policy)); 907 expectLastCall().andAnswer(future); 908 return future; 909 } 910 911 private Future<Void> expectMeteredIfacesChanged(String... ifaces) throws Exception { 912 final FutureAnswer future = new FutureAnswer(); 913 mPolicyListener.onMeteredIfacesChanged(aryEq(ifaces)); 914 expectLastCall().andAnswer(future); 915 return future; 916 } 917 918 private Future<Void> expectPolicyDataEnable(int type, boolean enabled) throws Exception { 919 // TODO: bring back this test 920 return null; 921 } 922 923 private void expectAdvisePersistThreshold() throws Exception { 924 mStatsService.advisePersistThreshold(anyLong()); 925 expectLastCall().anyTimes(); 926 } 927 928 private static class TestAbstractFuture<T> extends AbstractFuture<T> { 929 @Override 930 public T get() throws InterruptedException, ExecutionException { 931 try { 932 return get(5, TimeUnit.SECONDS); 933 } catch (TimeoutException e) { 934 throw new RuntimeException(e); 935 } 936 } 937 } 938 939 private static class FutureAnswer extends TestAbstractFuture<Void> implements IAnswer<Void> { 940 @Override 941 public Void answer() { 942 set(null); 943 return null; 944 } 945 } 946 947 private static class FutureCapture<T> extends TestAbstractFuture<T> { 948 public Capture<T> capture = new Capture<T>() { 949 @Override 950 public void setValue(T value) { 951 super.setValue(value); 952 set(value); 953 } 954 }; 955 } 956 957 private static class IdleFuture extends AbstractFuture<Void> implements IdleHandler { 958 @Override 959 public Void get() throws InterruptedException, ExecutionException { 960 try { 961 return get(5, TimeUnit.SECONDS); 962 } catch (TimeoutException e) { 963 throw new RuntimeException(e); 964 } 965 } 966 967 @Override 968 public boolean queueIdle() { 969 set(null); 970 return false; 971 } 972 } 973 974 /** 975 * Wait until {@link #mService} internal {@link Handler} is idle. 976 */ 977 private IdleFuture expectIdle() { 978 final IdleFuture future = new IdleFuture(); 979 mService.addIdleHandler(future); 980 return future; 981 } 982 983 private static void assertTimeEquals(long expected, long actual) { 984 if (expected != actual) { 985 fail("expected " + formatTime(expected) + " but was actually " + formatTime(actual)); 986 } 987 } 988 989 private static String formatTime(long millis) { 990 final Time time = new Time(Time.TIMEZONE_UTC); 991 time.set(millis); 992 return time.format3339(false); 993 } 994 995 private static void assertEqualsFuzzy(long expected, long actual, long fuzzy) { 996 final long low = expected - fuzzy; 997 final long high = expected + fuzzy; 998 if (actual < low || actual > high) { 999 fail("value " + actual + " is outside [" + low + "," + high + "]"); 1000 } 1001 } 1002 1003 private static void assertUnique(LinkedHashSet<Long> seen, Long value) { 1004 if (!seen.add(value)) { 1005 fail("found duplicate time " + value + " in series " + seen.toString()); 1006 } 1007 } 1008 1009 private static void assertNotificationType(int expected, String actualTag) { 1010 assertEquals( 1011 Integer.toString(expected), actualTag.substring(actualTag.lastIndexOf(':') + 1)); 1012 } 1013 1014 private long getElapsedRealtime() { 1015 return mElapsedRealtime; 1016 } 1017 1018 private void setCurrentTimeMillis(long currentTimeMillis) { 1019 mStartTime = currentTimeMillis; 1020 mElapsedRealtime = 0L; 1021 } 1022 1023 private long currentTimeMillis() { 1024 return mStartTime + mElapsedRealtime; 1025 } 1026 1027 private void incrementCurrentTime(long duration) { 1028 mElapsedRealtime += duration; 1029 } 1030 1031 private void replay() { 1032 EasyMock.replay(mActivityManager, mPowerManager, mStatsService, mPolicyListener, 1033 mNetworkManager, mTime, mConnManager, mNotifManager); 1034 } 1035 1036 private void verifyAndReset() { 1037 EasyMock.verify(mActivityManager, mPowerManager, mStatsService, mPolicyListener, 1038 mNetworkManager, mTime, mConnManager, mNotifManager); 1039 EasyMock.reset(mActivityManager, mPowerManager, mStatsService, mPolicyListener, 1040 mNetworkManager, mTime, mConnManager, mNotifManager); 1041 } 1042} 1043