NetworkPolicyManagerServiceTest.java revision d37948f6ed1667d077e0e3a38808f42f981ddcc2
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.NetworkPolicyManager.POLICY_NONE; 24import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND; 25import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL; 26import static android.net.NetworkPolicyManager.RULE_REJECT_METERED; 27import static android.net.NetworkPolicyManager.computeLastCycleBoundary; 28import static android.net.NetworkStats.TAG_NONE; 29import static android.net.NetworkStats.UID_ALL; 30import static android.net.NetworkTemplate.MATCH_WIFI; 31import static org.easymock.EasyMock.anyInt; 32import static org.easymock.EasyMock.aryEq; 33import static org.easymock.EasyMock.capture; 34import static org.easymock.EasyMock.createMock; 35import static org.easymock.EasyMock.eq; 36import static org.easymock.EasyMock.expect; 37import static org.easymock.EasyMock.expectLastCall; 38import static org.easymock.EasyMock.isA; 39 40import android.app.IActivityManager; 41import android.app.INotificationManager; 42import android.app.IProcessObserver; 43import android.content.Intent; 44import android.content.pm.PackageInfo; 45import android.content.pm.PackageManager; 46import android.content.pm.Signature; 47import android.net.ConnectivityManager; 48import android.net.IConnectivityManager; 49import android.net.INetworkPolicyListener; 50import android.net.INetworkStatsService; 51import android.net.LinkProperties; 52import android.net.NetworkInfo; 53import android.net.NetworkInfo.DetailedState; 54import android.net.NetworkPolicy; 55import android.net.NetworkState; 56import android.net.NetworkStats; 57import android.net.NetworkTemplate; 58import android.os.Binder; 59import android.os.INetworkManagementService; 60import android.os.IPowerManager; 61import android.test.AndroidTestCase; 62import android.test.mock.MockPackageManager; 63import android.test.suitebuilder.annotation.LargeTest; 64import android.test.suitebuilder.annotation.Suppress; 65import android.text.format.Time; 66import android.util.TrustedTime; 67 68import com.android.server.net.NetworkPolicyManagerService; 69import com.google.common.util.concurrent.AbstractFuture; 70 71import org.easymock.Capture; 72import org.easymock.EasyMock; 73import org.easymock.IAnswer; 74 75import java.io.File; 76import java.util.concurrent.ExecutionException; 77import java.util.concurrent.Future; 78import java.util.concurrent.TimeUnit; 79import java.util.concurrent.TimeoutException; 80 81/** 82 * Tests for {@link NetworkPolicyManagerService}. 83 */ 84@LargeTest 85public class NetworkPolicyManagerServiceTest extends AndroidTestCase { 86 private static final String TAG = "NetworkPolicyManagerServiceTest"; 87 88 private static final long TEST_START = 1194220800000L; 89 private static final String TEST_IFACE = "test0"; 90 91 private static NetworkTemplate sTemplateWifi = new NetworkTemplate(MATCH_WIFI, null); 92 93 private BroadcastInterceptingContext mServiceContext; 94 private File mPolicyDir; 95 96 private IActivityManager mActivityManager; 97 private IPowerManager mPowerManager; 98 private INetworkStatsService mStatsService; 99 private INetworkManagementService mNetworkManagement; 100 private INetworkPolicyListener mPolicyListener; 101 private TrustedTime mTime; 102 private IConnectivityManager mConnManager; 103 private INotificationManager mNotifManager; 104 105 private NetworkPolicyManagerService mService; 106 private IProcessObserver mProcessObserver; 107 108 private Binder mStubBinder = new Binder(); 109 110 private static final int UID_A = android.os.Process.FIRST_APPLICATION_UID + 800; 111 private static final int UID_B = android.os.Process.FIRST_APPLICATION_UID + 801; 112 113 private static final int PID_1 = 400; 114 private static final int PID_2 = 401; 115 private static final int PID_3 = 402; 116 117 @Override 118 public void setUp() throws Exception { 119 super.setUp(); 120 121 // intercept various broadcasts, and pretend that uids have packages 122 mServiceContext = new BroadcastInterceptingContext(getContext()) { 123 @Override 124 public PackageManager getPackageManager() { 125 return new MockPackageManager() { 126 @Override 127 public String[] getPackagesForUid(int uid) { 128 return new String[] { "com.example" }; 129 } 130 131 @Override 132 public PackageInfo getPackageInfo(String packageName, int flags) { 133 final PackageInfo info = new PackageInfo(); 134 final Signature signature; 135 if ("android".equals(packageName)) { 136 signature = new Signature("F00D"); 137 } else { 138 signature = new Signature("DEAD"); 139 } 140 info.signatures = new Signature[] { signature }; 141 return info; 142 } 143 }; 144 } 145 }; 146 147 mPolicyDir = getContext().getFilesDir(); 148 for (File file : mPolicyDir.listFiles()) { 149 file.delete(); 150 } 151 152 mActivityManager = createMock(IActivityManager.class); 153 mPowerManager = createMock(IPowerManager.class); 154 mStatsService = createMock(INetworkStatsService.class); 155 mNetworkManagement = createMock(INetworkManagementService.class); 156 mPolicyListener = createMock(INetworkPolicyListener.class); 157 mTime = createMock(TrustedTime.class); 158 mConnManager = createMock(IConnectivityManager.class); 159 mNotifManager = createMock(INotificationManager.class); 160 161 mService = new NetworkPolicyManagerService( 162 mServiceContext, mActivityManager, mPowerManager, mStatsService, 163 mNetworkManagement, mTime, mPolicyDir); 164 mService.bindConnectivityManager(mConnManager); 165 mService.bindNotificationManager(mNotifManager); 166 167 // RemoteCallbackList needs a binder to use as key 168 expect(mPolicyListener.asBinder()).andReturn(mStubBinder).atLeastOnce(); 169 replay(); 170 mService.registerListener(mPolicyListener); 171 verifyAndReset(); 172 173 // catch the registered IProcessObserver during systemReady() 174 final Capture<IProcessObserver> processObserver = new Capture<IProcessObserver>(); 175 mActivityManager.registerProcessObserver(capture(processObserver)); 176 expectLastCall().atLeastOnce(); 177 178 // expect to answer screen status during systemReady() 179 expect(mPowerManager.isScreenOn()).andReturn(true).atLeastOnce(); 180 expectTime(System.currentTimeMillis()); 181 182 // default behavior is background data enabled 183 expect(mConnManager.getBackgroundDataSetting()).andReturn(true); 184 185 replay(); 186 mService.systemReady(); 187 verifyAndReset(); 188 189 mProcessObserver = processObserver.getValue(); 190 191 } 192 193 @Override 194 public void tearDown() throws Exception { 195 for (File file : mPolicyDir.listFiles()) { 196 file.delete(); 197 } 198 199 mServiceContext = null; 200 mPolicyDir = null; 201 202 mActivityManager = null; 203 mPowerManager = null; 204 mStatsService = null; 205 mPolicyListener = null; 206 mTime = null; 207 208 mService = null; 209 mProcessObserver = null; 210 211 super.tearDown(); 212 } 213 214 @Suppress 215 public void testPolicyChangeTriggersBroadcast() throws Exception { 216 mService.setUidPolicy(UID_A, POLICY_NONE); 217 218 // change background policy and expect broadcast 219 final Future<Intent> backgroundChanged = mServiceContext.nextBroadcastIntent( 220 ConnectivityManager.ACTION_BACKGROUND_DATA_SETTING_CHANGED); 221 222 mService.setUidPolicy(UID_A, POLICY_REJECT_METERED_BACKGROUND); 223 224 backgroundChanged.get(); 225 } 226 227 public void testPidForegroundCombined() throws Exception { 228 // push all uid into background 229 mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, false); 230 mProcessObserver.onForegroundActivitiesChanged(PID_2, UID_A, false); 231 mProcessObserver.onForegroundActivitiesChanged(PID_3, UID_B, false); 232 assertFalse(mService.isUidForeground(UID_A)); 233 assertFalse(mService.isUidForeground(UID_B)); 234 235 // push one of the shared pids into foreground 236 mProcessObserver.onForegroundActivitiesChanged(PID_2, UID_A, true); 237 assertTrue(mService.isUidForeground(UID_A)); 238 assertFalse(mService.isUidForeground(UID_B)); 239 240 // and swap another uid into foreground 241 mProcessObserver.onForegroundActivitiesChanged(PID_2, UID_A, false); 242 mProcessObserver.onForegroundActivitiesChanged(PID_3, UID_B, true); 243 assertFalse(mService.isUidForeground(UID_A)); 244 assertTrue(mService.isUidForeground(UID_B)); 245 246 // push both pid into foreground 247 mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, true); 248 mProcessObserver.onForegroundActivitiesChanged(PID_2, UID_A, true); 249 assertTrue(mService.isUidForeground(UID_A)); 250 251 // pull one out, should still be foreground 252 mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, false); 253 assertTrue(mService.isUidForeground(UID_A)); 254 255 // pull final pid out, should now be background 256 mProcessObserver.onForegroundActivitiesChanged(PID_2, UID_A, false); 257 assertFalse(mService.isUidForeground(UID_A)); 258 } 259 260 public void testScreenChangesRules() throws Exception { 261 Future<Void> future; 262 263 expectSetUidNetworkRules(UID_A, false); 264 future = expectRulesChanged(UID_A, RULE_ALLOW_ALL); 265 replay(); 266 mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, true); 267 future.get(); 268 verifyAndReset(); 269 270 // push strict policy for foreground uid, verify ALLOW rule 271 expectSetUidNetworkRules(UID_A, false); 272 future = expectRulesChanged(UID_A, RULE_ALLOW_ALL); 273 replay(); 274 mService.setUidPolicy(UID_A, POLICY_REJECT_METERED_BACKGROUND); 275 future.get(); 276 verifyAndReset(); 277 278 // now turn screen off and verify REJECT rule 279 expect(mPowerManager.isScreenOn()).andReturn(false).atLeastOnce(); 280 expectSetUidNetworkRules(UID_A, true); 281 future = expectRulesChanged(UID_A, RULE_REJECT_METERED); 282 replay(); 283 mServiceContext.sendBroadcast(new Intent(Intent.ACTION_SCREEN_OFF)); 284 future.get(); 285 verifyAndReset(); 286 287 // and turn screen back on, verify ALLOW rule restored 288 expect(mPowerManager.isScreenOn()).andReturn(true).atLeastOnce(); 289 expectSetUidNetworkRules(UID_A, false); 290 future = expectRulesChanged(UID_A, RULE_ALLOW_ALL); 291 replay(); 292 mServiceContext.sendBroadcast(new Intent(Intent.ACTION_SCREEN_ON)); 293 future.get(); 294 verifyAndReset(); 295 } 296 297 public void testPolicyNone() throws Exception { 298 Future<Void> future; 299 300 expectSetUidNetworkRules(UID_A, false); 301 future = expectRulesChanged(UID_A, RULE_ALLOW_ALL); 302 replay(); 303 mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, true); 304 future.get(); 305 verifyAndReset(); 306 307 // POLICY_NONE should RULE_ALLOW in foreground 308 expectSetUidNetworkRules(UID_A, false); 309 future = expectRulesChanged(UID_A, RULE_ALLOW_ALL); 310 replay(); 311 mService.setUidPolicy(UID_A, POLICY_NONE); 312 future.get(); 313 verifyAndReset(); 314 315 // POLICY_NONE should RULE_ALLOW in background 316 expectSetUidNetworkRules(UID_A, false); 317 future = expectRulesChanged(UID_A, RULE_ALLOW_ALL); 318 replay(); 319 mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, false); 320 future.get(); 321 verifyAndReset(); 322 } 323 324 public void testPolicyReject() throws Exception { 325 Future<Void> future; 326 327 // POLICY_REJECT should RULE_ALLOW in background 328 expectSetUidNetworkRules(UID_A, true); 329 future = expectRulesChanged(UID_A, RULE_REJECT_METERED); 330 replay(); 331 mService.setUidPolicy(UID_A, POLICY_REJECT_METERED_BACKGROUND); 332 future.get(); 333 verifyAndReset(); 334 335 // POLICY_REJECT should RULE_ALLOW in foreground 336 expectSetUidNetworkRules(UID_A, false); 337 future = expectRulesChanged(UID_A, RULE_ALLOW_ALL); 338 replay(); 339 mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, true); 340 future.get(); 341 verifyAndReset(); 342 343 // POLICY_REJECT should RULE_REJECT in background 344 expectSetUidNetworkRules(UID_A, true); 345 future = expectRulesChanged(UID_A, RULE_REJECT_METERED); 346 replay(); 347 mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, false); 348 future.get(); 349 verifyAndReset(); 350 } 351 352 public void testPolicyRejectAddRemove() throws Exception { 353 Future<Void> future; 354 355 // POLICY_NONE should have RULE_ALLOW in background 356 expectSetUidNetworkRules(UID_A, false); 357 future = expectRulesChanged(UID_A, RULE_ALLOW_ALL); 358 replay(); 359 mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, false); 360 mService.setUidPolicy(UID_A, POLICY_NONE); 361 future.get(); 362 verifyAndReset(); 363 364 // adding POLICY_REJECT should cause RULE_REJECT 365 expectSetUidNetworkRules(UID_A, true); 366 future = expectRulesChanged(UID_A, RULE_REJECT_METERED); 367 replay(); 368 mService.setUidPolicy(UID_A, POLICY_REJECT_METERED_BACKGROUND); 369 future.get(); 370 verifyAndReset(); 371 372 // removing POLICY_REJECT should return us to RULE_ALLOW 373 expectSetUidNetworkRules(UID_A, false); 374 future = expectRulesChanged(UID_A, RULE_ALLOW_ALL); 375 replay(); 376 mService.setUidPolicy(UID_A, POLICY_NONE); 377 future.get(); 378 verifyAndReset(); 379 } 380 381 public void testLastCycleBoundaryThisMonth() throws Exception { 382 // assume cycle day of "5th", which should be in same month 383 final long currentTime = parseTime("2007-11-14T00:00:00.000Z"); 384 final long expectedCycle = parseTime("2007-11-05T00:00:00.000Z"); 385 386 final NetworkPolicy policy = new NetworkPolicy(sTemplateWifi, 5, 1024L, 1024L); 387 final long actualCycle = computeLastCycleBoundary(currentTime, policy); 388 assertEquals(expectedCycle, actualCycle); 389 } 390 391 public void testLastCycleBoundaryLastMonth() throws Exception { 392 // assume cycle day of "20th", which should be in last month 393 final long currentTime = parseTime("2007-11-14T00:00:00.000Z"); 394 final long expectedCycle = parseTime("2007-10-20T00:00:00.000Z"); 395 396 final NetworkPolicy policy = new NetworkPolicy(sTemplateWifi, 20, 1024L, 1024L); 397 final long actualCycle = computeLastCycleBoundary(currentTime, policy); 398 assertEquals(expectedCycle, actualCycle); 399 } 400 401 public void testLastCycleBoundaryThisMonthFebruary() throws Exception { 402 // assume cycle day of "30th" in february; should go to january 403 final long currentTime = parseTime("2007-02-14T00:00:00.000Z"); 404 final long expectedCycle = parseTime("2007-01-30T00:00:00.000Z"); 405 406 final NetworkPolicy policy = new NetworkPolicy(sTemplateWifi, 30, 1024L, 1024L); 407 final long actualCycle = computeLastCycleBoundary(currentTime, policy); 408 assertEquals(expectedCycle, actualCycle); 409 } 410 411 public void testLastCycleBoundaryLastMonthFebruary() throws Exception { 412 // assume cycle day of "30th" in february, which should clamp 413 final long currentTime = parseTime("2007-03-14T00:00:00.000Z"); 414 final long expectedCycle = parseTime("2007-03-01T00:00:00.000Z"); 415 416 final NetworkPolicy policy = new NetworkPolicy(sTemplateWifi, 30, 1024L, 1024L); 417 final long actualCycle = computeLastCycleBoundary(currentTime, policy); 418 assertEquals(expectedCycle, actualCycle); 419 } 420 421 public void testNetworkPolicyAppliedCycleLastMonth() throws Exception { 422 long elapsedRealtime = 0; 423 NetworkState[] state = null; 424 NetworkStats stats = null; 425 Future<Void> future; 426 427 final long TIME_FEB_15 = 1171497600000L; 428 final long TIME_MAR_10 = 1173484800000L; 429 final int CYCLE_DAY = 15; 430 431 // first, pretend that wifi network comes online. no policy active, 432 // which means we shouldn't push limit to interface. 433 state = new NetworkState[] { buildWifi() }; 434 expect(mConnManager.getAllNetworkState()).andReturn(state).atLeastOnce(); 435 expectTime(TIME_MAR_10 + elapsedRealtime); 436 future = expectMeteredIfacesChanged(); 437 438 replay(); 439 mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION)); 440 future.get(); 441 verifyAndReset(); 442 443 // now change cycle to be on 15th, and test in early march, to verify we 444 // pick cycle day in previous month. 445 expect(mConnManager.getAllNetworkState()).andReturn(state).atLeastOnce(); 446 expectTime(TIME_MAR_10 + elapsedRealtime); 447 448 // pretend that 512 bytes total have happened 449 stats = new NetworkStats(elapsedRealtime, 1) 450 .addValues(TEST_IFACE, UID_ALL, TAG_NONE, 256L, 2L, 256L, 2L); 451 expect(mStatsService.getSummaryForNetwork(sTemplateWifi, TIME_FEB_15, TIME_MAR_10)) 452 .andReturn(stats).atLeastOnce(); 453 454 // TODO: consider making strongly ordered mock 455 expectRemoveInterfaceQuota(TEST_IFACE); 456 expectSetInterfaceQuota(TEST_IFACE, 1536L); 457 458 expectClearNotifications(); 459 future = expectMeteredIfacesChanged(TEST_IFACE); 460 461 replay(); 462 setNetworkPolicies(new NetworkPolicy(sTemplateWifi, CYCLE_DAY, 1024L, 2048L)); 463 future.get(); 464 verifyAndReset(); 465 } 466 467 public void testUidRemovedPolicyCleared() throws Exception { 468 Future<Void> future; 469 470 // POLICY_REJECT should RULE_REJECT in background 471 expectSetUidNetworkRules(UID_A, true); 472 future = expectRulesChanged(UID_A, RULE_REJECT_METERED); 473 replay(); 474 mService.setUidPolicy(UID_A, POLICY_REJECT_METERED_BACKGROUND); 475 future.get(); 476 verifyAndReset(); 477 478 // uninstall should clear RULE_REJECT 479 expectSetUidNetworkRules(UID_A, false); 480 future = expectRulesChanged(UID_A, RULE_ALLOW_ALL); 481 replay(); 482 final Intent intent = new Intent(ACTION_UID_REMOVED); 483 intent.putExtra(EXTRA_UID, UID_A); 484 mServiceContext.sendBroadcast(intent); 485 future.get(); 486 verifyAndReset(); 487 } 488 489 private static long parseTime(String time) { 490 final Time result = new Time(); 491 result.parse3339(time); 492 return result.toMillis(true); 493 } 494 495 private void setNetworkPolicies(NetworkPolicy... policies) { 496 mService.setNetworkPolicies(policies); 497 } 498 499 private static NetworkState buildWifi() { 500 final NetworkInfo info = new NetworkInfo(TYPE_WIFI, 0, null, null); 501 info.setDetailedState(DetailedState.CONNECTED, null, null); 502 final LinkProperties prop = new LinkProperties(); 503 prop.setInterfaceName(TEST_IFACE); 504 return new NetworkState(info, prop, null); 505 } 506 507 private void expectTime(long currentTime) throws Exception { 508 expect(mTime.forceRefresh()).andReturn(false).anyTimes(); 509 expect(mTime.hasCache()).andReturn(true).anyTimes(); 510 expect(mTime.currentTimeMillis()).andReturn(currentTime).anyTimes(); 511 expect(mTime.getCacheAge()).andReturn(0L).anyTimes(); 512 expect(mTime.getCacheCertainty()).andReturn(0L).anyTimes(); 513 } 514 515 private void expectClearNotifications() throws Exception { 516 mNotifManager.cancelNotificationWithTag(isA(String.class), isA(String.class), anyInt()); 517 expectLastCall().anyTimes(); 518 } 519 520 private void expectSetInterfaceQuota(String iface, long quota) throws Exception { 521 mNetworkManagement.setInterfaceQuota(iface, quota); 522 expectLastCall().atLeastOnce(); 523 } 524 525 private void expectRemoveInterfaceQuota(String iface) throws Exception { 526 mNetworkManagement.removeInterfaceQuota(iface); 527 expectLastCall().atLeastOnce(); 528 } 529 530 private void expectSetUidNetworkRules(int uid, boolean rejectOnQuotaInterfaces) 531 throws Exception { 532 mNetworkManagement.setUidNetworkRules(uid, rejectOnQuotaInterfaces); 533 expectLastCall().atLeastOnce(); 534 } 535 536 private Future<Void> expectRulesChanged(int uid, int policy) throws Exception { 537 final FutureAnswer future = new FutureAnswer(); 538 mPolicyListener.onUidRulesChanged(eq(uid), eq(policy)); 539 expectLastCall().andAnswer(future); 540 return future; 541 } 542 543 private Future<Void> expectMeteredIfacesChanged(String... ifaces) throws Exception { 544 final FutureAnswer future = new FutureAnswer(); 545 mPolicyListener.onMeteredIfacesChanged(aryEq(ifaces)); 546 expectLastCall().andAnswer(future); 547 return future; 548 } 549 550 private static class FutureAnswer extends AbstractFuture<Void> implements IAnswer<Void> { 551 @Override 552 public Void get() throws InterruptedException, ExecutionException { 553 try { 554 return get(5, TimeUnit.SECONDS); 555 } catch (TimeoutException e) { 556 throw new RuntimeException(e); 557 } 558 } 559 560 @Override 561 public Void answer() { 562 set(null); 563 return null; 564 } 565 } 566 567 private void replay() { 568 EasyMock.replay(mActivityManager, mPowerManager, mStatsService, mPolicyListener, 569 mNetworkManagement, mTime, mConnManager, mNotifManager); 570 } 571 572 private void verifyAndReset() { 573 EasyMock.verify(mActivityManager, mPowerManager, mStatsService, mPolicyListener, 574 mNetworkManagement, mTime, mConnManager, mNotifManager); 575 EasyMock.reset(mActivityManager, mPowerManager, mStatsService, mPolicyListener, 576 mNetworkManagement, mTime, mConnManager, mNotifManager); 577 } 578} 579