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