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