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