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