NetworkPolicyManagerServiceTest.java revision cd2ca4038a027315832c38c68be5076000bc4b53
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.net.ConnectivityManager.CONNECTIVITY_ACTION; 20import static android.net.ConnectivityManager.TYPE_WIFI; 21import static android.net.NetworkPolicyManager.POLICY_NONE; 22import static android.net.NetworkPolicyManager.POLICY_REJECT_PAID_BACKGROUND; 23import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL; 24import static android.net.NetworkPolicyManager.RULE_REJECT_PAID; 25import static android.net.NetworkPolicyManager.computeLastCycleBoundary; 26import static android.net.NetworkStats.UID_ALL; 27import static android.net.TrafficStats.TEMPLATE_WIFI; 28import static org.easymock.EasyMock.capture; 29import static org.easymock.EasyMock.createMock; 30import static org.easymock.EasyMock.eq; 31import static org.easymock.EasyMock.expect; 32import static org.easymock.EasyMock.expectLastCall; 33 34import android.app.IActivityManager; 35import android.app.IProcessObserver; 36import android.content.Intent; 37import android.content.pm.PackageManager; 38import android.net.ConnectivityManager; 39import android.net.IConnectivityManager; 40import android.net.INetworkPolicyListener; 41import android.net.INetworkStatsService; 42import android.net.LinkProperties; 43import android.net.NetworkInfo; 44import android.net.NetworkInfo.DetailedState; 45import android.net.NetworkPolicy; 46import android.net.NetworkState; 47import android.net.NetworkStats; 48import android.os.Binder; 49import android.os.IPowerManager; 50import android.test.AndroidTestCase; 51import android.test.mock.MockPackageManager; 52import android.test.suitebuilder.annotation.LargeTest; 53import android.test.suitebuilder.annotation.Suppress; 54import android.text.format.Time; 55import android.util.TrustedTime; 56 57import com.android.server.net.NetworkPolicyManagerService; 58 59import org.easymock.Capture; 60import org.easymock.EasyMock; 61 62import java.io.File; 63import java.util.concurrent.Future; 64 65/** 66 * Tests for {@link NetworkPolicyManagerService}. 67 */ 68@LargeTest 69public class NetworkPolicyManagerServiceTest extends AndroidTestCase { 70 private static final String TAG = "NetworkPolicyManagerServiceTest"; 71 72 private static final long TEST_START = 1194220800000L; 73 private static final String TEST_IFACE = "test0"; 74 75 private BroadcastInterceptingContext mServiceContext; 76 private File mPolicyDir; 77 78 private IActivityManager mActivityManager; 79 private IPowerManager mPowerManager; 80 private INetworkStatsService mStatsService; 81 private INetworkPolicyListener mPolicyListener; 82 private TrustedTime mTime; 83 private IConnectivityManager mConnManager; 84 85 private NetworkPolicyManagerService mService; 86 private IProcessObserver mProcessObserver; 87 88 private Binder mStubBinder = new Binder(); 89 90 private static final int UID_A = 800; 91 private static final int UID_B = 801; 92 93 private static final int PID_1 = 400; 94 private static final int PID_2 = 401; 95 private static final int PID_3 = 402; 96 97 @Override 98 public void setUp() throws Exception { 99 super.setUp(); 100 101 // intercept various broadcasts, and pretend that uids have packages 102 mServiceContext = new BroadcastInterceptingContext(getContext()) { 103 @Override 104 public PackageManager getPackageManager() { 105 return new MockPackageManager() { 106 @Override 107 public String[] getPackagesForUid(int uid) { 108 return new String[] { "com.example" }; 109 } 110 }; 111 } 112 }; 113 114 mPolicyDir = getContext().getFilesDir(); 115 116 mActivityManager = createMock(IActivityManager.class); 117 mPowerManager = createMock(IPowerManager.class); 118 mStatsService = createMock(INetworkStatsService.class); 119 mPolicyListener = createMock(INetworkPolicyListener.class); 120 mTime = createMock(TrustedTime.class); 121 mConnManager = createMock(IConnectivityManager.class); 122 123 mService = new NetworkPolicyManagerService( 124 mServiceContext, mActivityManager, mPowerManager, mStatsService, mTime, mPolicyDir); 125 mService.bindConnectivityManager(mConnManager); 126 127 // RemoteCallbackList needs a binder to use as key 128 expect(mPolicyListener.asBinder()).andReturn(mStubBinder).atLeastOnce(); 129 replay(); 130 mService.registerListener(mPolicyListener); 131 verifyAndReset(); 132 133 // catch the registered IProcessObserver during systemReady() 134 final Capture<IProcessObserver> processObserver = new Capture<IProcessObserver>(); 135 mActivityManager.registerProcessObserver(capture(processObserver)); 136 expectLastCall().atLeastOnce(); 137 138 // expect to answer screen status during systemReady() 139 expect(mPowerManager.isScreenOn()).andReturn(true).atLeastOnce(); 140 141 replay(); 142 mService.systemReady(); 143 verifyAndReset(); 144 145 mProcessObserver = processObserver.getValue(); 146 147 } 148 149 @Override 150 public void tearDown() throws Exception { 151 for (File file : mPolicyDir.listFiles()) { 152 file.delete(); 153 } 154 155 mServiceContext = null; 156 mPolicyDir = null; 157 158 mActivityManager = null; 159 mPowerManager = null; 160 mStatsService = null; 161 mPolicyListener = null; 162 mTime = null; 163 164 mService = null; 165 mProcessObserver = null; 166 167 super.tearDown(); 168 } 169 170 @Suppress 171 public void testPolicyChangeTriggersBroadcast() throws Exception { 172 mService.setUidPolicy(UID_A, POLICY_NONE); 173 174 // change background policy and expect broadcast 175 final Future<Intent> backgroundChanged = mServiceContext.nextBroadcastIntent( 176 ConnectivityManager.ACTION_BACKGROUND_DATA_SETTING_CHANGED); 177 178 mService.setUidPolicy(UID_A, POLICY_REJECT_PAID_BACKGROUND); 179 180 backgroundChanged.get(); 181 } 182 183 public void testPidForegroundCombined() throws Exception { 184 // push all uid into background 185 mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, false); 186 mProcessObserver.onForegroundActivitiesChanged(PID_2, UID_A, false); 187 mProcessObserver.onForegroundActivitiesChanged(PID_3, UID_B, false); 188 assertFalse(mService.isUidForeground(UID_A)); 189 assertFalse(mService.isUidForeground(UID_B)); 190 191 // push one of the shared pids into foreground 192 mProcessObserver.onForegroundActivitiesChanged(PID_2, UID_A, true); 193 assertTrue(mService.isUidForeground(UID_A)); 194 assertFalse(mService.isUidForeground(UID_B)); 195 196 // and swap another uid into foreground 197 mProcessObserver.onForegroundActivitiesChanged(PID_2, UID_A, false); 198 mProcessObserver.onForegroundActivitiesChanged(PID_3, UID_B, true); 199 assertFalse(mService.isUidForeground(UID_A)); 200 assertTrue(mService.isUidForeground(UID_B)); 201 202 // push both pid into foreground 203 mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, true); 204 mProcessObserver.onForegroundActivitiesChanged(PID_2, UID_A, true); 205 assertTrue(mService.isUidForeground(UID_A)); 206 207 // pull one out, should still be foreground 208 mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, false); 209 assertTrue(mService.isUidForeground(UID_A)); 210 211 // pull final pid out, should now be background 212 mProcessObserver.onForegroundActivitiesChanged(PID_2, UID_A, false); 213 assertFalse(mService.isUidForeground(UID_A)); 214 } 215 216 public void testScreenChangesRules() throws Exception { 217 // push strict policy for foreground uid, verify ALLOW rule 218 expectRulesChanged(UID_A, RULE_ALLOW_ALL); 219 replay(); 220 mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, true); 221 mService.setUidPolicy(UID_A, POLICY_REJECT_PAID_BACKGROUND); 222 verifyAndReset(); 223 224 // now turn screen off and verify REJECT rule 225 expect(mPowerManager.isScreenOn()).andReturn(false).atLeastOnce(); 226 expectRulesChanged(UID_A, RULE_REJECT_PAID); 227 replay(); 228 mServiceContext.sendBroadcast(new Intent(Intent.ACTION_SCREEN_OFF)); 229 verifyAndReset(); 230 231 // and turn screen back on, verify ALLOW rule restored 232 expect(mPowerManager.isScreenOn()).andReturn(true).atLeastOnce(); 233 expectRulesChanged(UID_A, RULE_ALLOW_ALL); 234 replay(); 235 mServiceContext.sendBroadcast(new Intent(Intent.ACTION_SCREEN_ON)); 236 verifyAndReset(); 237 } 238 239 public void testPolicyNone() throws Exception { 240 // POLICY_NONE should RULE_ALLOW in foreground 241 expectRulesChanged(UID_A, RULE_ALLOW_ALL); 242 replay(); 243 mService.setUidPolicy(UID_A, POLICY_NONE); 244 mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, true); 245 verifyAndReset(); 246 247 // POLICY_NONE should RULE_ALLOW in background 248 expectRulesChanged(UID_A, RULE_ALLOW_ALL); 249 replay(); 250 mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, false); 251 verifyAndReset(); 252 } 253 254 public void testPolicyReject() throws Exception { 255 // POLICY_REJECT should RULE_ALLOW in background 256 expectRulesChanged(UID_A, RULE_REJECT_PAID); 257 replay(); 258 mService.setUidPolicy(UID_A, POLICY_REJECT_PAID_BACKGROUND); 259 verifyAndReset(); 260 261 // POLICY_REJECT should RULE_ALLOW in foreground 262 expectRulesChanged(UID_A, RULE_ALLOW_ALL); 263 replay(); 264 mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, true); 265 verifyAndReset(); 266 267 // POLICY_REJECT should RULE_REJECT in background 268 expectRulesChanged(UID_A, RULE_REJECT_PAID); 269 replay(); 270 mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, false); 271 verifyAndReset(); 272 } 273 274 public void testPolicyRejectAddRemove() throws Exception { 275 // POLICY_NONE should have RULE_ALLOW in background 276 expectRulesChanged(UID_A, RULE_ALLOW_ALL); 277 replay(); 278 mService.setUidPolicy(UID_A, POLICY_NONE); 279 mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, false); 280 verifyAndReset(); 281 282 // adding POLICY_REJECT should cause RULE_REJECT 283 expectRulesChanged(UID_A, RULE_REJECT_PAID); 284 replay(); 285 mService.setUidPolicy(UID_A, POLICY_REJECT_PAID_BACKGROUND); 286 verifyAndReset(); 287 288 // removing POLICY_REJECT should return us to RULE_ALLOW 289 expectRulesChanged(UID_A, RULE_ALLOW_ALL); 290 replay(); 291 mService.setUidPolicy(UID_A, POLICY_NONE); 292 verifyAndReset(); 293 } 294 295 public void testLastCycleBoundaryThisMonth() throws Exception { 296 // assume cycle day of "5th", which should be in same month 297 final long currentTime = parseTime("2007-11-14T00:00:00.000Z"); 298 final long expectedCycle = parseTime("2007-11-05T00:00:00.000Z"); 299 300 final NetworkPolicy policy = new NetworkPolicy(5, 1024L, 1024L); 301 final long actualCycle = computeLastCycleBoundary(currentTime, policy); 302 assertEquals(expectedCycle, actualCycle); 303 } 304 305 public void testLastCycleBoundaryLastMonth() throws Exception { 306 // assume cycle day of "20th", which should be in last month 307 final long currentTime = parseTime("2007-11-14T00:00:00.000Z"); 308 final long expectedCycle = parseTime("2007-10-20T00:00:00.000Z"); 309 310 final NetworkPolicy policy = new NetworkPolicy(20, 1024L, 1024L); 311 final long actualCycle = computeLastCycleBoundary(currentTime, policy); 312 assertEquals(expectedCycle, actualCycle); 313 } 314 315 public void testLastCycleBoundaryThisMonthFebruary() throws Exception { 316 // assume cycle day of "30th" in february; should go to january 317 final long currentTime = parseTime("2007-02-14T00:00:00.000Z"); 318 final long expectedCycle = parseTime("2007-01-30T00:00:00.000Z"); 319 320 final NetworkPolicy policy = new NetworkPolicy(30, 1024L, 1024L); 321 final long actualCycle = computeLastCycleBoundary(currentTime, policy); 322 assertEquals(expectedCycle, actualCycle); 323 } 324 325 public void testLastCycleBoundaryLastMonthFebruary() throws Exception { 326 // assume cycle day of "30th" in february, which should clamp 327 final long currentTime = parseTime("2007-03-14T00:00:00.000Z"); 328 final long expectedCycle = parseTime("2007-03-01T00:00:00.000Z"); 329 330 final NetworkPolicy policy = new NetworkPolicy(30, 1024L, 1024L); 331 final long actualCycle = computeLastCycleBoundary(currentTime, policy); 332 assertEquals(expectedCycle, actualCycle); 333 } 334 335 public void testNetworkPolicyAppliedCycleLastMonth() throws Exception { 336 long elapsedRealtime = 0; 337 NetworkState[] state = null; 338 NetworkStats stats = null; 339 340 final long TIME_FEB_15 = 1171497600000L; 341 final long TIME_MAR_10 = 1173484800000L; 342 final int CYCLE_DAY = 15; 343 344 // first, pretend that wifi network comes online. no policy active, 345 // which means we shouldn't push limit to interface. 346 state = new NetworkState[] { buildWifi() }; 347 expect(mConnManager.getAllNetworkState()).andReturn(state).atLeastOnce(); 348 expectTime(TIME_MAR_10 + elapsedRealtime); 349 350 replay(); 351 mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION)); 352 verifyAndReset(); 353 354 // now change cycle to be on 15th, and test in early march, to verify we 355 // pick cycle day in previous month. 356 expect(mConnManager.getAllNetworkState()).andReturn(state).atLeastOnce(); 357 expectTime(TIME_MAR_10 + elapsedRealtime); 358 359 // pretend that 512 bytes total have happened 360 stats = new NetworkStats.Builder(elapsedRealtime, 1).addEntry( 361 TEST_IFACE, UID_ALL, 256L, 256L).build(); 362 expect(mStatsService.getSummaryForNetwork(TIME_FEB_15, TIME_MAR_10, TEMPLATE_WIFI, null)) 363 .andReturn(stats).atLeastOnce(); 364 365 // expect that quota remaining should be 1536 bytes 366 // TODO: write up NetworkManagementService mock 367 368 replay(); 369 mService.setNetworkPolicy(TEMPLATE_WIFI, null, new NetworkPolicy(CYCLE_DAY, 1024L, 2048L)); 370 verifyAndReset(); 371 } 372 373 private static long parseTime(String time) { 374 final Time result = new Time(); 375 result.parse3339(time); 376 return result.toMillis(true); 377 } 378 379 private static NetworkState buildWifi() { 380 final NetworkInfo info = new NetworkInfo(TYPE_WIFI, 0, null, null); 381 info.setDetailedState(DetailedState.CONNECTED, null, null); 382 final LinkProperties prop = new LinkProperties(); 383 prop.setInterfaceName(TEST_IFACE); 384 return new NetworkState(info, prop, null); 385 } 386 387 public void expectTime(long currentTime) throws Exception { 388 expect(mTime.forceRefresh()).andReturn(false).anyTimes(); 389 expect(mTime.hasCache()).andReturn(true).anyTimes(); 390 expect(mTime.currentTimeMillis()).andReturn(currentTime).anyTimes(); 391 expect(mTime.getCacheAge()).andReturn(0L).anyTimes(); 392 expect(mTime.getCacheCertainty()).andReturn(0L).anyTimes(); 393 } 394 395 private void expectRulesChanged(int uid, int policy) throws Exception { 396 mPolicyListener.onRulesChanged(eq(uid), eq(policy)); 397 expectLastCall().atLeastOnce(); 398 } 399 400 private void replay() { 401 EasyMock.replay(mActivityManager, mPowerManager, mStatsService, mPolicyListener, mTime, 402 mConnManager); 403 } 404 405 private void verifyAndReset() { 406 EasyMock.verify(mActivityManager, mPowerManager, mStatsService, mPolicyListener, mTime, 407 mConnManager); 408 EasyMock.reset(mActivityManager, mPowerManager, mStatsService, mPolicyListener, mTime, 409 mConnManager); 410 } 411} 412