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