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