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