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