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