NetworkPolicyManagerServiceTest.java revision 5614bf5a1ae4522dfc1a041f003cebc9b25c8b93
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.NetworkPolicy.LIMIT_DISABLED; 22import static android.net.NetworkPolicy.WARNING_DISABLED; 23import static android.net.NetworkPolicyManager.POLICY_ALLOW_METERED_BACKGROUND; 24import static android.net.NetworkPolicyManager.POLICY_NONE; 25import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND; 26import static android.net.NetworkPolicyManager.computeLastCycleBoundary; 27import static android.net.NetworkPolicyManager.computeNextCycleBoundary; 28import static android.net.NetworkPolicyManager.uidPoliciesToString; 29import static android.net.TrafficStats.KB_IN_BYTES; 30import static android.net.TrafficStats.MB_IN_BYTES; 31import static android.text.format.DateUtils.DAY_IN_MILLIS; 32import static android.text.format.DateUtils.MINUTE_IN_MILLIS; 33import static android.text.format.Time.TIMEZONE_UTC; 34 35import static com.android.server.net.NetworkPolicyManagerService.TYPE_LIMIT; 36import static com.android.server.net.NetworkPolicyManagerService.TYPE_LIMIT_SNOOZED; 37import static com.android.server.net.NetworkPolicyManagerService.TYPE_WARNING; 38 39import static org.junit.Assert.assertEquals; 40import static org.junit.Assert.assertFalse; 41import static org.junit.Assert.assertNotNull; 42import static org.junit.Assert.assertNull; 43import static org.junit.Assert.assertTrue; 44import static org.junit.Assert.fail; 45import static org.mockito.Matchers.any; 46import static org.mockito.Matchers.anyBoolean; 47import static org.mockito.Matchers.anyInt; 48import static org.mockito.Matchers.anyLong; 49import static org.mockito.Matchers.anyString; 50import static org.mockito.Matchers.eq; 51import static org.mockito.Matchers.isA; 52import static org.mockito.Mockito.atLeastOnce; 53import static org.mockito.Mockito.doAnswer; 54import static org.mockito.Mockito.mock; 55import static org.mockito.Mockito.never; 56import static org.mockito.Mockito.verify; 57import static org.mockito.Mockito.when; 58 59import android.Manifest; 60import android.app.ActivityManager; 61import android.app.IActivityManager; 62import android.app.INotificationManager; 63import android.app.IUidObserver; 64import android.app.Notification; 65import android.app.usage.UsageStatsManagerInternal; 66import android.content.Context; 67import android.content.Intent; 68import android.content.pm.ApplicationInfo; 69import android.content.pm.IPackageManager; 70import android.content.pm.PackageInfo; 71import android.content.pm.PackageManager; 72import android.content.pm.Signature; 73import android.net.ConnectivityManager; 74import android.net.IConnectivityManager; 75import android.net.INetworkManagementEventObserver; 76import android.net.INetworkPolicyListener; 77import android.net.INetworkStatsService; 78import android.net.LinkProperties; 79import android.net.NetworkInfo; 80import android.net.NetworkPolicyManager; 81import android.net.NetworkInfo.DetailedState; 82import android.net.NetworkPolicy; 83import android.net.NetworkState; 84import android.net.NetworkStats; 85import android.net.NetworkTemplate; 86import android.os.Binder; 87import android.os.INetworkManagementService; 88import android.os.PowerManagerInternal; 89import android.os.UserHandle; 90import android.support.test.InstrumentationRegistry; 91import android.support.test.filters.MediumTest; 92import android.support.test.runner.AndroidJUnit4; 93import android.text.TextUtils; 94import android.text.format.Time; 95import android.util.Log; 96import android.util.TrustedTime; 97 98import com.android.internal.util.test.BroadcastInterceptingContext; 99import com.android.internal.util.test.BroadcastInterceptingContext.FutureIntent; 100import com.android.server.net.NetworkPolicyManagerInternal; 101import com.android.server.net.NetworkPolicyManagerService; 102 103import libcore.io.IoUtils; 104import libcore.io.Streams; 105 106import com.google.common.util.concurrent.AbstractFuture; 107 108import org.junit.After; 109import org.junit.Before; 110import org.junit.BeforeClass; 111import org.junit.Rule; 112import org.junit.Test; 113import org.junit.rules.MethodRule; 114import org.junit.runner.RunWith; 115import org.junit.runners.model.FrameworkMethod; 116import org.junit.runners.model.Statement; 117import org.mockito.ArgumentCaptor; 118import org.mockito.Mock; 119import org.mockito.MockitoAnnotations; 120import org.mockito.invocation.InvocationOnMock; 121import org.mockito.stubbing.Answer; 122 123import java.io.File; 124import java.io.FileOutputStream; 125import java.io.InputStream; 126import java.io.OutputStream; 127import java.lang.annotation.Annotation; 128import java.lang.annotation.ElementType; 129import java.lang.annotation.Retention; 130import java.lang.annotation.RetentionPolicy; 131import java.lang.annotation.Target; 132import java.util.Arrays; 133import java.util.LinkedHashSet; 134import java.util.List; 135import java.util.concurrent.CountDownLatch; 136import java.util.concurrent.ExecutionException; 137import java.util.concurrent.Future; 138import java.util.concurrent.TimeUnit; 139import java.util.concurrent.TimeoutException; 140import java.util.stream.Collectors; 141 142/** 143 * Tests for {@link NetworkPolicyManagerService}. 144 */ 145@RunWith(AndroidJUnit4.class) 146@MediumTest 147public class NetworkPolicyManagerServiceTest { 148 private static final String TAG = "NetworkPolicyManagerServiceTest"; 149 150 private static final long TEST_START = 1194220800000L; 151 private static final String TEST_IFACE = "test0"; 152 private static final String TEST_SSID = "AndroidAP"; 153 154 private static NetworkTemplate sTemplateWifi = NetworkTemplate.buildTemplateWifi(TEST_SSID); 155 156 /** 157 * Path on assets where files used by {@link NetPolicyXml} are located. 158 */ 159 private static final String NETPOLICY_DIR = "NetworkPolicyManagerServiceTest/netpolicy"; 160 161 private BroadcastInterceptingContext mServiceContext; 162 private File mPolicyDir; 163 164 /** 165 * Relative path of the XML file that will be used as {@code netpolicy.xml}. 166 * 167 * <p>Typically set through a {@link NetPolicyXml} annotation in the test method. 168 */ 169 private String mNetpolicyXml; 170 171 private @Mock IActivityManager mActivityManager; 172 private @Mock INetworkStatsService mStatsService; 173 private @Mock INetworkManagementService mNetworkManager; 174 private @Mock TrustedTime mTime; 175 private @Mock IConnectivityManager mConnManager; 176 private @Mock INotificationManager mNotifManager; 177 private @Mock PackageManager mPackageManager; 178 private @Mock IPackageManager mIpm; 179 180 private IUidObserver mUidObserver; 181 private INetworkManagementEventObserver mNetworkObserver; 182 183 private NetworkPolicyListenerAnswer mPolicyListener; 184 private NetworkPolicyManagerService mService; 185 186 private long mStartTime; 187 private long mElapsedRealtime; 188 189 private static final int USER_ID = 0; 190 191 private static final int APP_ID_A = android.os.Process.FIRST_APPLICATION_UID + 4; 192 private static final int APP_ID_B = android.os.Process.FIRST_APPLICATION_UID + 8; 193 private static final int APP_ID_C = android.os.Process.FIRST_APPLICATION_UID + 15; 194 private static final int APP_ID_D = android.os.Process.FIRST_APPLICATION_UID + 16; 195 private static final int APP_ID_E = android.os.Process.FIRST_APPLICATION_UID + 23; 196 private static final int APP_ID_F = android.os.Process.FIRST_APPLICATION_UID + 42; 197 198 private static final int UID_A = UserHandle.getUid(USER_ID, APP_ID_A); 199 private static final int UID_B = UserHandle.getUid(USER_ID, APP_ID_B); 200 private static final int UID_C = UserHandle.getUid(USER_ID, APP_ID_C); 201 private static final int UID_D = UserHandle.getUid(USER_ID, APP_ID_D); 202 private static final int UID_E = UserHandle.getUid(USER_ID, APP_ID_E); 203 private static final int UID_F = UserHandle.getUid(USER_ID, APP_ID_F); 204 205 private static final String PKG_NAME_A = "name.is.A,pkg.A"; 206 207 public final @Rule NetPolicyMethodRule mNetPolicyXmlRule = new NetPolicyMethodRule(); 208 209 @BeforeClass 210 public static void registerLocalServices() { 211 addLocalServiceMock(PowerManagerInternal.class); 212 addLocalServiceMock(DeviceIdleController.LocalService.class); 213 final UsageStatsManagerInternal usageStats = 214 addLocalServiceMock(UsageStatsManagerInternal.class); 215 when(usageStats.getIdleUidsForUser(anyInt())).thenReturn(new int[]{}); 216 } 217 218 @Before 219 public void callSystemReady() throws Exception { 220 MockitoAnnotations.initMocks(this); 221 222 final Context context = InstrumentationRegistry.getContext(); 223 224 setCurrentTimeMillis(TEST_START); 225 226 // intercept various broadcasts, and pretend that uids have packages 227 mServiceContext = new BroadcastInterceptingContext(context) { 228 @Override 229 public PackageManager getPackageManager() { 230 return mPackageManager; 231 } 232 233 @Override 234 public void startActivity(Intent intent) { 235 // ignored 236 } 237 }; 238 239 setNetpolicyXml(context); 240 241 doAnswer(new Answer<Void>() { 242 243 @Override 244 public Void answer(InvocationOnMock invocation) throws Throwable { 245 mUidObserver = (IUidObserver) invocation.getArguments()[0]; 246 Log.d(TAG, "set mUidObserver to " + mUidObserver); 247 return null; 248 } 249 }).when(mActivityManager).registerUidObserver(any(), anyInt(), 250 ActivityManager.PROCESS_STATE_UNKNOWN, null); 251 252 mService = new NetworkPolicyManagerService(mServiceContext, mActivityManager, mStatsService, 253 mNetworkManager, mIpm, mTime, mPolicyDir, true); 254 mService.bindConnectivityManager(mConnManager); 255 mService.bindNotificationManager(mNotifManager); 256 mPolicyListener = new NetworkPolicyListenerAnswer(mService); 257 258 // Sets some common expectations. 259 when(mPackageManager.getPackageInfo(anyString(), anyInt())).thenAnswer( 260 new Answer<PackageInfo>() { 261 262 @Override 263 public PackageInfo answer(InvocationOnMock invocation) throws Throwable { 264 final String packageName = (String) invocation.getArguments()[0]; 265 final PackageInfo info = new PackageInfo(); 266 final Signature signature; 267 if ("android".equals(packageName)) { 268 signature = new Signature("F00D"); 269 } else { 270 signature = new Signature("DEAD"); 271 } 272 info.signatures = new Signature[] { 273 signature 274 }; 275 return info; 276 } 277 }); 278 when(mPackageManager.getApplicationInfoAsUser(anyString(), anyInt(), anyInt())) 279 .thenReturn(new ApplicationInfo()); 280 when(mPackageManager.getPackagesForUid(UID_A)).thenReturn(new String[] {PKG_NAME_A}); 281 when(mNetworkManager.isBandwidthControlEnabled()).thenReturn(true); 282 expectCurrentTime(); 283 284 // Prepare NPMS. 285 mService.systemReady(); 286 287 // catch INetworkManagementEventObserver during systemReady() 288 final ArgumentCaptor<INetworkManagementEventObserver> networkObserver = 289 ArgumentCaptor.forClass(INetworkManagementEventObserver.class); 290 verify(mNetworkManager).registerObserver(networkObserver.capture()); 291 mNetworkObserver = networkObserver.getValue(); 292 } 293 294 @After 295 public void removeFiles() throws Exception { 296 for (File file : mPolicyDir.listFiles()) { 297 file.delete(); 298 } 299 } 300 301 @After 302 public void unregisterLocalServices() throws Exception { 303 // Registered by NetworkPolicyManagerService's constructor. 304 LocalServices.removeServiceForTest(NetworkPolicyManagerInternal.class); 305 } 306 307 @Test 308 public void testTurnRestrictBackgroundOn() throws Exception { 309 assertRestrictBackgroundOff(); // Sanity check. 310 final FutureIntent futureIntent = newRestrictBackgroundChangedFuture(); 311 setRestrictBackground(true); 312 assertRestrictBackgroundChangedReceived(futureIntent, null); 313 } 314 315 @Test 316 @NetPolicyXml("restrict-background-on.xml") 317 public void testTurnRestrictBackgroundOff() throws Exception { 318 assertRestrictBackgroundOn(); // Sanity check. 319 final FutureIntent futureIntent = newRestrictBackgroundChangedFuture(); 320 setRestrictBackground(false); 321 assertRestrictBackgroundChangedReceived(futureIntent, null); 322 } 323 324 /** 325 * Adds whitelist when restrict background is on - app should receive an intent. 326 */ 327 @Test 328 @NetPolicyXml("restrict-background-on.xml") 329 public void testAddRestrictBackgroundWhitelist_restrictBackgroundOn() throws Exception { 330 assertRestrictBackgroundOn(); // Sanity check. 331 addRestrictBackgroundWhitelist(true); 332 } 333 334 /** 335 * Adds whitelist when restrict background is off - app should not receive an intent. 336 */ 337 @Test 338 public void testAddRestrictBackgroundWhitelist_restrictBackgroundOff() throws Exception { 339 assertRestrictBackgroundOff(); // Sanity check. 340 addRestrictBackgroundWhitelist(false); 341 } 342 343 private void addRestrictBackgroundWhitelist(boolean expectIntent) throws Exception { 344 // Sanity checks. 345 assertWhitelistUids(); 346 assertUidPolicy(UID_A, POLICY_NONE); 347 348 final FutureIntent futureIntent = newRestrictBackgroundChangedFuture(); 349 mPolicyListener.expect().onUidPoliciesChanged(anyInt(), anyInt()); 350 351 mService.setUidPolicy(UID_A, POLICY_ALLOW_METERED_BACKGROUND); 352 353 assertWhitelistUids(UID_A); 354 assertUidPolicy(UID_A, POLICY_ALLOW_METERED_BACKGROUND); 355 mPolicyListener.waitAndVerify() 356 .onUidPoliciesChanged(APP_ID_A, POLICY_ALLOW_METERED_BACKGROUND); 357 if (expectIntent) { 358 assertRestrictBackgroundChangedReceived(futureIntent, PKG_NAME_A); 359 } else { 360 futureIntent.assertNotReceived(); 361 } 362 } 363 364 /** 365 * Removes whitelist when restrict background is on - app should receive an intent. 366 */ 367 @Test 368 @NetPolicyXml("uidA-whitelisted-restrict-background-on.xml") 369 public void testRemoveRestrictBackgroundWhitelist_restrictBackgroundOn() throws Exception { 370 assertRestrictBackgroundOn(); // Sanity check. 371 removeRestrictBackgroundWhitelist(true); 372 } 373 374 /** 375 * Removes whitelist when restrict background is off - app should not receive an intent. 376 */ 377 @Test 378 @NetPolicyXml("uidA-whitelisted-restrict-background-off.xml") 379 public void testRemoveRestrictBackgroundWhitelist_restrictBackgroundOff() throws Exception { 380 assertRestrictBackgroundOff(); // Sanity check. 381 removeRestrictBackgroundWhitelist(false); 382 } 383 384 private void removeRestrictBackgroundWhitelist(boolean expectIntent) throws Exception { 385 // Sanity checks. 386 assertWhitelistUids(UID_A); 387 assertUidPolicy(UID_A, POLICY_ALLOW_METERED_BACKGROUND); 388 389 final FutureIntent futureIntent = newRestrictBackgroundChangedFuture(); 390 mPolicyListener.expect().onUidPoliciesChanged(anyInt(), anyInt()); 391 392 mService.setUidPolicy(UID_A, POLICY_NONE); 393 394 assertWhitelistUids(); 395 assertUidPolicy(UID_A, POLICY_NONE); 396 mPolicyListener.waitAndVerify().onUidPoliciesChanged(APP_ID_A, POLICY_NONE); 397 if (expectIntent) { 398 assertRestrictBackgroundChangedReceived(futureIntent, PKG_NAME_A); 399 } else { 400 futureIntent.assertNotReceived(); 401 } 402 } 403 404 /** 405 * Adds blacklist when restrict background is on - app should not receive an intent. 406 */ 407 @Test 408 @NetPolicyXml("restrict-background-on.xml") 409 public void testAddRestrictBackgroundBlacklist_restrictBackgroundOn() throws Exception { 410 assertRestrictBackgroundOn(); // Sanity check. 411 addRestrictBackgroundBlacklist(false); 412 } 413 414 /** 415 * Adds blacklist when restrict background is off - app should receive an intent. 416 */ 417 @Test 418 public void testAddRestrictBackgroundBlacklist_restrictBackgroundOff() throws Exception { 419 assertRestrictBackgroundOff(); // Sanity check. 420 addRestrictBackgroundBlacklist(true); 421 } 422 423 private void addRestrictBackgroundBlacklist(boolean expectIntent) throws Exception { 424 assertUidPolicy(UID_A, POLICY_NONE); // Sanity check. 425 final FutureIntent futureIntent = newRestrictBackgroundChangedFuture(); 426 mPolicyListener.expect().onUidPoliciesChanged(anyInt(), anyInt()); 427 428 mService.setUidPolicy(UID_A, POLICY_REJECT_METERED_BACKGROUND); 429 430 assertUidPolicy(UID_A, POLICY_REJECT_METERED_BACKGROUND); 431 mPolicyListener.waitAndVerify() 432 .onUidPoliciesChanged(APP_ID_A, POLICY_REJECT_METERED_BACKGROUND); 433 if (expectIntent) { 434 assertRestrictBackgroundChangedReceived(futureIntent, PKG_NAME_A); 435 } else { 436 futureIntent.assertNotReceived(); 437 } 438 } 439 440 /** 441 * Removes blacklist when restrict background is on - app should not receive an intent. 442 */ 443 @Test 444 @NetPolicyXml("uidA-blacklisted-restrict-background-on.xml") 445 public void testRemoveRestrictBackgroundBlacklist_restrictBackgroundOn() throws Exception { 446 assertRestrictBackgroundOn(); // Sanity check. 447 removeRestrictBackgroundBlacklist(false); 448 } 449 450 /** 451 * Removes blacklist when restrict background is off - app should receive an intent. 452 */ 453 @Test 454 @NetPolicyXml("uidA-blacklisted-restrict-background-off.xml") 455 public void testRemoveRestrictBackgroundBlacklist_restrictBackgroundOff() throws Exception { 456 assertRestrictBackgroundOff(); // Sanity check. 457 removeRestrictBackgroundBlacklist(true); 458 } 459 460 private void removeRestrictBackgroundBlacklist(boolean expectIntent) throws Exception { 461 assertUidPolicy(UID_A, POLICY_REJECT_METERED_BACKGROUND); // Sanity check. 462 final FutureIntent futureIntent = newRestrictBackgroundChangedFuture(); 463 mPolicyListener.expect().onUidPoliciesChanged(anyInt(), anyInt()); 464 465 mService.setUidPolicy(UID_A, POLICY_NONE); 466 467 assertUidPolicy(UID_A, POLICY_NONE); 468 mPolicyListener.waitAndVerify() 469 .onUidPoliciesChanged(APP_ID_A, POLICY_NONE); 470 if (expectIntent) { 471 assertRestrictBackgroundChangedReceived(futureIntent, PKG_NAME_A); 472 } else { 473 futureIntent.assertNotReceived(); 474 } 475 } 476 477 @Test 478 @NetPolicyXml("uidA-blacklisted-restrict-background-on.xml") 479 public void testBlacklistedAppIsNotNotifiedWhenRestrictBackgroundIsOn() throws Exception { 480 // Sanity checks. 481 assertRestrictBackgroundOn(); 482 assertUidPolicy(UID_A, POLICY_REJECT_METERED_BACKGROUND); 483 484 final FutureIntent futureIntent = newRestrictBackgroundChangedFuture(); 485 setRestrictBackground(true); 486 futureIntent.assertNotReceived(); 487 } 488 489 @Test 490 @NetPolicyXml("uidA-whitelisted-restrict-background-on.xml") 491 public void testWhitelistedAppIsNotNotifiedWhenRestrictBackgroundIsOn() throws Exception { 492 // Sanity checks. 493 assertRestrictBackgroundOn(); 494 assertWhitelistUids(UID_A); 495 496 final FutureIntent futureIntent = newRestrictBackgroundChangedFuture(); 497 setRestrictBackground(true); 498 futureIntent.assertNotReceived(); 499 } 500 501 @Test 502 @NetPolicyXml("uidA-whitelisted-restrict-background-on.xml") 503 public void testWhitelistedAppIsNotifiedWhenBlacklisted() throws Exception { 504 // Sanity checks. 505 assertRestrictBackgroundOn(); 506 assertWhitelistUids(UID_A); 507 508 final FutureIntent futureIntent = newRestrictBackgroundChangedFuture(); 509 mService.setUidPolicy(UID_A, POLICY_REJECT_METERED_BACKGROUND); 510 assertRestrictBackgroundChangedReceived(futureIntent, PKG_NAME_A); 511 } 512 513 @Test 514 @NetPolicyXml("restrict-background-lists-whitelist-format.xml") 515 public void testRestrictBackgroundLists_whitelistFormat() throws Exception { 516 restrictBackgroundListsTest(); 517 } 518 519 @Test 520 @NetPolicyXml("restrict-background-lists-uid-policy-format.xml") 521 public void testRestrictBackgroundLists_uidPolicyFormat() throws Exception { 522 restrictBackgroundListsTest(); 523 } 524 525 private void restrictBackgroundListsTest() throws Exception { 526 // UIds that are whitelisted. 527 assertWhitelistUids(UID_A, UID_B, UID_C); 528 assertUidPolicy(UID_A, POLICY_ALLOW_METERED_BACKGROUND); 529 assertUidPolicy(UID_B, POLICY_ALLOW_METERED_BACKGROUND); 530 assertUidPolicy(UID_C, POLICY_ALLOW_METERED_BACKGROUND); 531 532 // UIDs that are blacklisted. 533 assertUidPolicy(UID_D, POLICY_NONE); 534 assertUidPolicy(UID_E, POLICY_REJECT_METERED_BACKGROUND); 535 536 // UIDS that have legacy policies. 537 assertUidPolicy(UID_F, 2); // POLICY_ALLOW_BACKGROUND_BATTERY_SAVE 538 539 // Remove whitelist. 540 mService.setUidPolicy(UID_A, POLICY_NONE); 541 assertUidPolicy(UID_A, POLICY_NONE); 542 assertWhitelistUids(UID_B, UID_C); 543 544 // Add whitelist when blacklisted. 545 mService.setUidPolicy(UID_E, POLICY_ALLOW_METERED_BACKGROUND); 546 assertUidPolicy(UID_E, POLICY_ALLOW_METERED_BACKGROUND); 547 assertWhitelistUids(UID_B, UID_C, UID_E); 548 549 // Add blacklist when whitelisted. 550 mService.setUidPolicy(UID_B, POLICY_REJECT_METERED_BACKGROUND); 551 assertUidPolicy(UID_B, POLICY_REJECT_METERED_BACKGROUND); 552 assertWhitelistUids(UID_C, UID_E); 553 } 554 555 /** 556 * Tests scenario where an UID had {@code restrict-background} and {@code uid-policy} tags. 557 */ 558 @Test 559 @NetPolicyXml("restrict-background-lists-mixed-format.xml") 560 public void testRestrictBackgroundLists_mixedFormat() throws Exception { 561 assertWhitelistUids(UID_A, UID_C, UID_D); 562 assertUidPolicy(UID_A, POLICY_ALLOW_METERED_BACKGROUND); 563 assertUidPolicy(UID_B, POLICY_REJECT_METERED_BACKGROUND); // Blacklist prevails. 564 assertUidPolicy(UID_C, (POLICY_ALLOW_METERED_BACKGROUND | 2)); 565 assertUidPolicy(UID_D, POLICY_ALLOW_METERED_BACKGROUND); 566 } 567 568 @Test 569 @NetPolicyXml("uids-with-mixed-policies.xml") 570 public void testGetUidsWithPolicy() throws Exception { 571 assertContainsInAnyOrder(mService.getUidsWithPolicy(POLICY_NONE)); 572 assertContainsInAnyOrder(mService.getUidsWithPolicy(POLICY_REJECT_METERED_BACKGROUND), 573 UID_B, UID_D); 574 assertContainsInAnyOrder(mService.getUidsWithPolicy(POLICY_ALLOW_METERED_BACKGROUND), 575 UID_E, UID_F); 576 // Legacy (POLICY_ALLOW_BACKGROUND_BATTERY_SAVE) 577 assertContainsInAnyOrder(mService.getUidsWithPolicy(2), 578 UID_C, UID_D, UID_F); 579 } 580 581 // NOTE: testPolicyChangeTriggersListener() is too superficial, they 582 // don't check for side-effects (like calls to NetworkManagementService) neither cover all 583 // different modes (Data Saver, Battery Saver, Doze, App idle, etc...). 584 // These scenarios are extensively tested on CTS' HostsideRestrictBackgroundNetworkTests. 585 @Test 586 public void testUidForeground() throws Exception { 587 // push all uids into background 588 mUidObserver.onUidStateChanged(UID_A, ActivityManager.PROCESS_STATE_SERVICE); 589 mUidObserver.onUidStateChanged(UID_B, ActivityManager.PROCESS_STATE_SERVICE); 590 assertFalse(mService.isUidForeground(UID_A)); 591 assertFalse(mService.isUidForeground(UID_B)); 592 593 // push one of the uids into foreground 594 mUidObserver.onUidStateChanged(UID_A, ActivityManager.PROCESS_STATE_TOP); 595 assertTrue(mService.isUidForeground(UID_A)); 596 assertFalse(mService.isUidForeground(UID_B)); 597 598 // and swap another uid into foreground 599 mUidObserver.onUidStateChanged(UID_A, ActivityManager.PROCESS_STATE_SERVICE); 600 mUidObserver.onUidStateChanged(UID_B, ActivityManager.PROCESS_STATE_TOP); 601 assertFalse(mService.isUidForeground(UID_A)); 602 assertTrue(mService.isUidForeground(UID_B)); 603 } 604 605 @Test 606 public void testLastCycleBoundaryThisMonth() throws Exception { 607 // assume cycle day of "5th", which should be in same month 608 final long currentTime = parseTime("2007-11-14T00:00:00.000Z"); 609 final long expectedCycle = parseTime("2007-11-05T00:00:00.000Z"); 610 611 final NetworkPolicy policy = new NetworkPolicy( 612 sTemplateWifi, 5, TIMEZONE_UTC, 1024L, 1024L, false); 613 final long actualCycle = computeLastCycleBoundary(currentTime, policy); 614 assertTimeEquals(expectedCycle, actualCycle); 615 } 616 617 @Test 618 public void testLastCycleBoundaryLastMonth() throws Exception { 619 // assume cycle day of "20th", which should be in last month 620 final long currentTime = parseTime("2007-11-14T00:00:00.000Z"); 621 final long expectedCycle = parseTime("2007-10-20T00:00:00.000Z"); 622 623 final NetworkPolicy policy = new NetworkPolicy( 624 sTemplateWifi, 20, TIMEZONE_UTC, 1024L, 1024L, false); 625 final long actualCycle = computeLastCycleBoundary(currentTime, policy); 626 assertTimeEquals(expectedCycle, actualCycle); 627 } 628 629 @Test 630 public void testLastCycleBoundaryThisMonthFebruary() throws Exception { 631 // assume cycle day of "30th" in february; should go to january 632 final long currentTime = parseTime("2007-02-14T00:00:00.000Z"); 633 final long expectedCycle = parseTime("2007-01-30T00:00:00.000Z"); 634 635 final NetworkPolicy policy = new NetworkPolicy( 636 sTemplateWifi, 30, TIMEZONE_UTC, 1024L, 1024L, false); 637 final long actualCycle = computeLastCycleBoundary(currentTime, policy); 638 assertTimeEquals(expectedCycle, actualCycle); 639 } 640 641 @Test 642 public void testLastCycleBoundaryLastMonthFebruary() throws Exception { 643 // assume cycle day of "30th" in february, which should clamp 644 final long currentTime = parseTime("2007-03-14T00:00:00.000Z"); 645 final long expectedCycle = parseTime("2007-02-28T23:59:59.000Z"); 646 647 final NetworkPolicy policy = new NetworkPolicy( 648 sTemplateWifi, 30, TIMEZONE_UTC, 1024L, 1024L, false); 649 final long actualCycle = computeLastCycleBoundary(currentTime, policy); 650 assertTimeEquals(expectedCycle, actualCycle); 651 } 652 653 @Test 654 public void testCycleBoundaryLeapYear() throws Exception { 655 final NetworkPolicy policy = new NetworkPolicy( 656 sTemplateWifi, 29, TIMEZONE_UTC, 1024L, 1024L, false); 657 658 assertTimeEquals(parseTime("2012-01-29T00:00:00.000Z"), 659 computeNextCycleBoundary(parseTime("2012-01-14T00:00:00.000Z"), policy)); 660 assertTimeEquals(parseTime("2012-02-29T00:00:00.000Z"), 661 computeNextCycleBoundary(parseTime("2012-02-14T00:00:00.000Z"), policy)); 662 assertTimeEquals(parseTime("2012-02-29T00:00:00.000Z"), 663 computeLastCycleBoundary(parseTime("2012-03-14T00:00:00.000Z"), policy)); 664 assertTimeEquals(parseTime("2012-03-29T00:00:00.000Z"), 665 computeNextCycleBoundary(parseTime("2012-03-14T00:00:00.000Z"), policy)); 666 667 assertTimeEquals(parseTime("2007-01-29T00:00:00.000Z"), 668 computeNextCycleBoundary(parseTime("2007-01-14T00:00:00.000Z"), policy)); 669 assertTimeEquals(parseTime("2007-02-28T23:59:59.000Z"), 670 computeNextCycleBoundary(parseTime("2007-02-14T00:00:00.000Z"), policy)); 671 assertTimeEquals(parseTime("2007-02-28T23:59:59.000Z"), 672 computeLastCycleBoundary(parseTime("2007-03-14T00:00:00.000Z"), policy)); 673 assertTimeEquals(parseTime("2007-03-29T00:00:00.000Z"), 674 computeNextCycleBoundary(parseTime("2007-03-14T00:00:00.000Z"), policy)); 675 } 676 677 @Test 678 public void testNextCycleTimezoneAfterUtc() throws Exception { 679 // US/Central is UTC-6 680 final NetworkPolicy policy = new NetworkPolicy( 681 sTemplateWifi, 10, "US/Central", 1024L, 1024L, false); 682 assertTimeEquals(parseTime("2012-01-10T06:00:00.000Z"), 683 computeNextCycleBoundary(parseTime("2012-01-05T00:00:00.000Z"), policy)); 684 } 685 686 @Test 687 public void testNextCycleTimezoneBeforeUtc() throws Exception { 688 // Israel is UTC+2 689 final NetworkPolicy policy = new NetworkPolicy( 690 sTemplateWifi, 10, "Israel", 1024L, 1024L, false); 691 assertTimeEquals(parseTime("2012-01-09T22:00:00.000Z"), 692 computeNextCycleBoundary(parseTime("2012-01-05T00:00:00.000Z"), policy)); 693 } 694 695 @Test 696 public void testNextCycleSane() throws Exception { 697 final NetworkPolicy policy = new NetworkPolicy( 698 sTemplateWifi, 31, TIMEZONE_UTC, WARNING_DISABLED, LIMIT_DISABLED, false); 699 final LinkedHashSet<Long> seen = new LinkedHashSet<Long>(); 700 701 // walk forwards, ensuring that cycle boundaries don't get stuck 702 long currentCycle = computeNextCycleBoundary(parseTime("2011-08-01T00:00:00.000Z"), policy); 703 for (int i = 0; i < 128; i++) { 704 long nextCycle = computeNextCycleBoundary(currentCycle, policy); 705 assertEqualsFuzzy(DAY_IN_MILLIS * 30, nextCycle - currentCycle, DAY_IN_MILLIS * 3); 706 assertUnique(seen, nextCycle); 707 currentCycle = nextCycle; 708 } 709 } 710 711 @Test 712 public void testLastCycleSane() throws Exception { 713 final NetworkPolicy policy = new NetworkPolicy( 714 sTemplateWifi, 31, TIMEZONE_UTC, WARNING_DISABLED, LIMIT_DISABLED, false); 715 final LinkedHashSet<Long> seen = new LinkedHashSet<Long>(); 716 717 // walk backwards, ensuring that cycle boundaries look sane 718 long currentCycle = computeLastCycleBoundary(parseTime("2011-08-04T00:00:00.000Z"), policy); 719 for (int i = 0; i < 128; i++) { 720 long lastCycle = computeLastCycleBoundary(currentCycle, policy); 721 assertEqualsFuzzy(DAY_IN_MILLIS * 30, currentCycle - lastCycle, DAY_IN_MILLIS * 3); 722 assertUnique(seen, lastCycle); 723 currentCycle = lastCycle; 724 } 725 } 726 727 @Test 728 public void testCycleTodayJanuary() throws Exception { 729 final NetworkPolicy policy = new NetworkPolicy( 730 sTemplateWifi, 14, "US/Pacific", 1024L, 1024L, false); 731 732 assertTimeEquals(parseTime("2013-01-14T00:00:00.000-08:00"), 733 computeNextCycleBoundary(parseTime("2013-01-13T23:59:59.000-08:00"), policy)); 734 assertTimeEquals(parseTime("2013-02-14T00:00:00.000-08:00"), 735 computeNextCycleBoundary(parseTime("2013-01-14T00:00:01.000-08:00"), policy)); 736 assertTimeEquals(parseTime("2013-02-14T00:00:00.000-08:00"), 737 computeNextCycleBoundary(parseTime("2013-01-14T15:11:00.000-08:00"), policy)); 738 739 assertTimeEquals(parseTime("2012-12-14T00:00:00.000-08:00"), 740 computeLastCycleBoundary(parseTime("2013-01-13T23:59:59.000-08:00"), policy)); 741 assertTimeEquals(parseTime("2013-01-14T00:00:00.000-08:00"), 742 computeLastCycleBoundary(parseTime("2013-01-14T00:00:01.000-08:00"), policy)); 743 assertTimeEquals(parseTime("2013-01-14T00:00:00.000-08:00"), 744 computeLastCycleBoundary(parseTime("2013-01-14T15:11:00.000-08:00"), policy)); 745 } 746 747 @Test 748 public void testLastCycleBoundaryDST() throws Exception { 749 final long currentTime = parseTime("1989-01-02T07:30:00.000"); 750 final long expectedCycle = parseTime("1988-12-03T02:00:00.000Z"); 751 752 final NetworkPolicy policy = new NetworkPolicy( 753 sTemplateWifi, 3, "America/Argentina/Buenos_Aires", 1024L, 1024L, false); 754 final long actualCycle = computeLastCycleBoundary(currentTime, policy); 755 assertTimeEquals(expectedCycle, actualCycle); 756 } 757 758 @Test 759 public void testNetworkPolicyAppliedCycleLastMonth() throws Exception { 760 NetworkState[] state = null; 761 NetworkStats stats = null; 762 763 final long TIME_FEB_15 = 1171497600000L; 764 final long TIME_MAR_10 = 1173484800000L; 765 final int CYCLE_DAY = 15; 766 767 setCurrentTimeMillis(TIME_MAR_10); 768 769 // first, pretend that wifi network comes online. no policy active, 770 // which means we shouldn't push limit to interface. 771 state = new NetworkState[] { buildWifi() }; 772 when(mConnManager.getAllNetworkState()).thenReturn(state); 773 expectCurrentTime(); 774 775 mPolicyListener.expect().onMeteredIfacesChanged(any()); 776 mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION)); 777 mPolicyListener.waitAndVerify().onMeteredIfacesChanged(any()); 778 779 // now change cycle to be on 15th, and test in early march, to verify we 780 // pick cycle day in previous month. 781 when(mConnManager.getAllNetworkState()).thenReturn(state); 782 expectCurrentTime(); 783 784 // pretend that 512 bytes total have happened 785 stats = new NetworkStats(getElapsedRealtime(), 1) 786 .addIfaceValues(TEST_IFACE, 256L, 2L, 256L, 2L); 787 when(mStatsService.getNetworkTotalBytes(sTemplateWifi, TIME_FEB_15, TIME_MAR_10)) 788 .thenReturn(stats.getTotalBytes()); 789 790 mPolicyListener.expect().onMeteredIfacesChanged(any()); 791 setNetworkPolicies(new NetworkPolicy( 792 sTemplateWifi, CYCLE_DAY, TIMEZONE_UTC, 1 * MB_IN_BYTES, 2 * MB_IN_BYTES, false)); 793 mPolicyListener.waitAndVerify().onMeteredIfacesChanged(eq(new String[]{TEST_IFACE})); 794 795 // TODO: consider making strongly ordered mock 796 verifyPolicyDataEnable(TYPE_WIFI, true); 797 verifyRemoveInterfaceQuota(TEST_IFACE); 798 verifySetInterfaceQuota(TEST_IFACE, (2 * MB_IN_BYTES) - 512); 799 } 800 801 @Test 802 public void testOverWarningLimitNotification() throws Exception { 803 NetworkState[] state = null; 804 NetworkStats stats = null; 805 Future<String> tagFuture = null; 806 807 final long TIME_FEB_15 = 1171497600000L; 808 final long TIME_MAR_10 = 1173484800000L; 809 final int CYCLE_DAY = 15; 810 811 setCurrentTimeMillis(TIME_MAR_10); 812 813 // assign wifi policy 814 state = new NetworkState[] {}; 815 stats = new NetworkStats(getElapsedRealtime(), 1) 816 .addIfaceValues(TEST_IFACE, 0L, 0L, 0L, 0L); 817 818 { 819 expectCurrentTime(); 820 when(mConnManager.getAllNetworkState()).thenReturn(state); 821 when(mStatsService.getNetworkTotalBytes(sTemplateWifi, TIME_FEB_15, 822 currentTimeMillis())).thenReturn(stats.getTotalBytes()); 823 824 mPolicyListener.expect().onMeteredIfacesChanged(any()); 825 setNetworkPolicies(new NetworkPolicy(sTemplateWifi, CYCLE_DAY, TIMEZONE_UTC, 1 826 * MB_IN_BYTES, 2 * MB_IN_BYTES, false)); 827 mPolicyListener.waitAndVerify().onMeteredIfacesChanged(any()); 828 verifyPolicyDataEnable(TYPE_WIFI, true); 829 } 830 831 // bring up wifi network 832 incrementCurrentTime(MINUTE_IN_MILLIS); 833 state = new NetworkState[] { buildWifi() }; 834 stats = new NetworkStats(getElapsedRealtime(), 1) 835 .addIfaceValues(TEST_IFACE, 0L, 0L, 0L, 0L); 836 837 { 838 expectCurrentTime(); 839 when(mConnManager.getAllNetworkState()).thenReturn(state); 840 when(mStatsService.getNetworkTotalBytes(sTemplateWifi, TIME_FEB_15, 841 currentTimeMillis())).thenReturn(stats.getTotalBytes()); 842 843 mPolicyListener.expect().onMeteredIfacesChanged(any()); 844 mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION)); 845 mPolicyListener.waitAndVerify().onMeteredIfacesChanged(eq(new String[]{TEST_IFACE})); 846 847 verifyPolicyDataEnable(TYPE_WIFI, true); 848 verifyRemoveInterfaceQuota(TEST_IFACE); 849 verifySetInterfaceQuota(TEST_IFACE, 2 * MB_IN_BYTES); 850 } 851 852 // go over warning, which should kick notification 853 incrementCurrentTime(MINUTE_IN_MILLIS); 854 stats = new NetworkStats(getElapsedRealtime(), 1) 855 .addIfaceValues(TEST_IFACE, 1536 * KB_IN_BYTES, 15L, 0L, 0L); 856 857 { 858 expectCurrentTime(); 859 when(mStatsService.getNetworkTotalBytes(sTemplateWifi, TIME_FEB_15, 860 currentTimeMillis())).thenReturn(stats.getTotalBytes()); 861 tagFuture = expectEnqueueNotification(); 862 863 mNetworkObserver.limitReached(null, TEST_IFACE); 864 865 assertNotificationType(TYPE_WARNING, tagFuture.get()); 866 verifyPolicyDataEnable(TYPE_WIFI, true); 867 868 } 869 870 // go over limit, which should kick notification and dialog 871 incrementCurrentTime(MINUTE_IN_MILLIS); 872 stats = new NetworkStats(getElapsedRealtime(), 1) 873 .addIfaceValues(TEST_IFACE, 5 * MB_IN_BYTES, 512L, 0L, 0L); 874 875 { 876 expectCurrentTime(); 877 when(mStatsService.getNetworkTotalBytes(sTemplateWifi, TIME_FEB_15, 878 currentTimeMillis())).thenReturn(stats.getTotalBytes()); 879 tagFuture = expectEnqueueNotification(); 880 881 mNetworkObserver.limitReached(null, TEST_IFACE); 882 883 assertNotificationType(TYPE_LIMIT, tagFuture.get()); 884 verifyPolicyDataEnable(TYPE_WIFI, false); 885 } 886 887 // now snooze policy, which should remove quota 888 incrementCurrentTime(MINUTE_IN_MILLIS); 889 890 { 891 expectCurrentTime(); 892 when(mConnManager.getAllNetworkState()).thenReturn(state); 893 when(mStatsService.getNetworkTotalBytes(sTemplateWifi, TIME_FEB_15, 894 currentTimeMillis())).thenReturn(stats.getTotalBytes()); 895 tagFuture = expectEnqueueNotification(); 896 897 mPolicyListener.expect().onMeteredIfacesChanged(any()); 898 mService.snoozeLimit(sTemplateWifi); 899 mPolicyListener.waitAndVerify().onMeteredIfacesChanged(eq(new String[]{TEST_IFACE})); 900 901 assertNotificationType(TYPE_LIMIT_SNOOZED, tagFuture.get()); 902 // snoozed interface still has high quota so background data is 903 // still restricted. 904 verifyRemoveInterfaceQuota(TEST_IFACE); 905 verifySetInterfaceQuota(TEST_IFACE, Long.MAX_VALUE); 906 verifyPolicyDataEnable(TYPE_WIFI, true); 907 } 908 } 909 910 @Test 911 public void testMeteredNetworkWithoutLimit() throws Exception { 912 NetworkState[] state = null; 913 NetworkStats stats = null; 914 915 final long TIME_FEB_15 = 1171497600000L; 916 final long TIME_MAR_10 = 1173484800000L; 917 final int CYCLE_DAY = 15; 918 919 setCurrentTimeMillis(TIME_MAR_10); 920 921 // bring up wifi network with metered policy 922 state = new NetworkState[] { buildWifi() }; 923 stats = new NetworkStats(getElapsedRealtime(), 1) 924 .addIfaceValues(TEST_IFACE, 0L, 0L, 0L, 0L); 925 926 { 927 expectCurrentTime(); 928 when(mConnManager.getAllNetworkState()).thenReturn(state); 929 when(mStatsService.getNetworkTotalBytes(sTemplateWifi, TIME_FEB_15, 930 currentTimeMillis())).thenReturn(stats.getTotalBytes()); 931 932 mPolicyListener.expect().onMeteredIfacesChanged(any()); 933 setNetworkPolicies(new NetworkPolicy( 934 sTemplateWifi, CYCLE_DAY, TIMEZONE_UTC, WARNING_DISABLED, LIMIT_DISABLED, 935 true)); 936 mPolicyListener.waitAndVerify().onMeteredIfacesChanged(eq(new String[]{TEST_IFACE})); 937 938 verifyPolicyDataEnable(TYPE_WIFI, true); 939 verifyRemoveInterfaceQuota(TEST_IFACE); 940 verifySetInterfaceQuota(TEST_IFACE, Long.MAX_VALUE); 941 } 942 } 943 944 private static long parseTime(String time) { 945 final Time result = new Time(); 946 result.parse3339(time); 947 return result.toMillis(true); 948 } 949 950 private void setNetworkPolicies(NetworkPolicy... policies) { 951 mService.setNetworkPolicies(policies); 952 } 953 954 private static NetworkState buildWifi() { 955 final NetworkInfo info = new NetworkInfo(TYPE_WIFI, 0, null, null); 956 info.setDetailedState(DetailedState.CONNECTED, null, null); 957 final LinkProperties prop = new LinkProperties(); 958 prop.setInterfaceName(TEST_IFACE); 959 return new NetworkState(info, prop, null, null, null, TEST_SSID); 960 } 961 962 private void expectCurrentTime() throws Exception { 963 when(mTime.forceRefresh()).thenReturn(false); 964 when(mTime.hasCache()).thenReturn(true); 965 when(mTime.currentTimeMillis()).thenReturn(currentTimeMillis()); 966 when(mTime.getCacheAge()).thenReturn(0L); 967 when(mTime.getCacheCertainty()).thenReturn(0L); 968 } 969 970 private Future<String> expectEnqueueNotification() throws Exception { 971 final FutureAnswer<String> futureAnswer = new FutureAnswer<String>(2); 972 doAnswer(futureAnswer).when(mNotifManager).enqueueNotificationWithTag( 973 anyString(), anyString(), anyString() /* capture here (index 2)*/, 974 anyInt(), isA(Notification.class), isA(int[].class), anyInt()); 975 return futureAnswer; 976 } 977 978 private void expectHasInternetPermission(int uid, boolean hasIt) throws Exception { 979 when(mIpm.checkUidPermission(Manifest.permission.INTERNET, uid)).thenReturn( 980 hasIt ? PackageManager.PERMISSION_GRANTED : PackageManager.PERMISSION_DENIED); 981 } 982 983 private void verifySetInterfaceQuota(String iface, long quotaBytes) throws Exception { 984 verify(mNetworkManager, atLeastOnce()).setInterfaceQuota(iface, quotaBytes); 985 } 986 987 private void verifyRemoveInterfaceQuota(String iface) throws Exception { 988 verify(mNetworkManager, atLeastOnce()).removeInterfaceQuota(iface); 989 } 990 991 private Future<Void> verifyPolicyDataEnable(int type, boolean enabled) throws Exception { 992 // TODO: bring back this test 993 return null; 994 } 995 996 private void verifyAdvisePersistThreshold() throws Exception { 997 verify(mStatsService).advisePersistThreshold(anyLong()); 998 } 999 1000 private static class TestAbstractFuture<T> extends AbstractFuture<T> { 1001 @Override 1002 public T get() throws InterruptedException, ExecutionException { 1003 try { 1004 return get(5, TimeUnit.SECONDS); 1005 } catch (TimeoutException e) { 1006 throw new RuntimeException(e); 1007 } 1008 } 1009 } 1010 1011 private static class FutureAnswer<T> extends TestAbstractFuture<T> implements Answer<Void> { 1012 private final int index; 1013 1014 FutureAnswer(int index) { 1015 this.index = index; 1016 } 1017 @Override 1018 public Void answer(InvocationOnMock invocation) throws Throwable { 1019 @SuppressWarnings("unchecked") 1020 T captured = (T) invocation.getArguments()[index]; 1021 set(captured); 1022 return null; 1023 } 1024 } 1025 1026 private static void assertTimeEquals(long expected, long actual) { 1027 if (expected != actual) { 1028 fail("expected " + formatTime(expected) + " but was actually " + formatTime(actual)); 1029 } 1030 } 1031 1032 private static String formatTime(long millis) { 1033 final Time time = new Time(Time.TIMEZONE_UTC); 1034 time.set(millis); 1035 return time.format3339(false); 1036 } 1037 1038 private static void assertEqualsFuzzy(long expected, long actual, long fuzzy) { 1039 final long low = expected - fuzzy; 1040 final long high = expected + fuzzy; 1041 if (actual < low || actual > high) { 1042 fail("value " + actual + " is outside [" + low + "," + high + "]"); 1043 } 1044 } 1045 1046 private static void assertUnique(LinkedHashSet<Long> seen, Long value) { 1047 if (!seen.add(value)) { 1048 fail("found duplicate time " + value + " in series " + seen.toString()); 1049 } 1050 } 1051 1052 private static void assertNotificationType(int expected, String actualTag) { 1053 assertEquals("notification type mismatch for '" + actualTag +"'", 1054 Integer.toString(expected), actualTag.substring(actualTag.lastIndexOf(':') + 1)); 1055 } 1056 1057 private void assertUidPolicy(int uid, int expected) { 1058 final int actual = mService.getUidPolicy(uid); 1059 if (expected != actual) { 1060 fail("Wrong policy for UID " + uid + ": expected " + uidPoliciesToString(expected) 1061 + ", actual " + uidPoliciesToString(actual)); 1062 } 1063 } 1064 1065 private void assertWhitelistUids(int... uids) { 1066 assertContainsInAnyOrder(mService.getUidsWithPolicy(POLICY_ALLOW_METERED_BACKGROUND), uids); 1067 } 1068 1069 private void assertRestrictBackgroundOn() throws Exception { 1070 assertTrue("restrictBackground should be set", mService.getRestrictBackground()); 1071 } 1072 1073 private void assertRestrictBackgroundOff() throws Exception { 1074 assertFalse("restrictBackground should not be set", mService.getRestrictBackground()); 1075 } 1076 1077 private FutureIntent newRestrictBackgroundChangedFuture() { 1078 return mServiceContext 1079 .nextBroadcastIntent(ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED); 1080 } 1081 1082 private void assertRestrictBackgroundChangedReceived(Future<Intent> future, 1083 String expectedPackage) throws Exception { 1084 final String action = ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED; 1085 final Intent intent = future.get(5, TimeUnit.SECONDS); 1086 assertNotNull("Didn't get a " + action + "intent in 5 seconds"); 1087 assertEquals("Wrong package on " + action + " intent", expectedPackage, intent.getPackage()); 1088 } 1089 1090 // TODO: replace by Truth, Hamcrest, or a similar tool. 1091 private void assertContainsInAnyOrder(int[] actual, int...expected) { 1092 final StringBuilder errors = new StringBuilder(); 1093 if (actual.length != expected.length) { 1094 errors.append("\tsize does not match\n"); 1095 } 1096 final List<Integer> actualList = 1097 Arrays.stream(actual).boxed().collect(Collectors.<Integer>toList()); 1098 final List<Integer> expectedList = 1099 Arrays.stream(expected).boxed().collect(Collectors.<Integer>toList()); 1100 if (!actualList.containsAll(expectedList)) { 1101 errors.append("\tmissing elements on actual list\n"); 1102 } 1103 if (!expectedList.containsAll(actualList)) { 1104 errors.append("\tmissing elements on expected list\n"); 1105 } 1106 if (errors.length() > 0) { 1107 fail("assertContainsInAnyOrder(expected=" + Arrays.toString(expected) 1108 + ", actual=" + Arrays.toString(actual) +") failed: \n" + errors); 1109 } 1110 } 1111 1112 private long getElapsedRealtime() { 1113 return mElapsedRealtime; 1114 } 1115 1116 private void setCurrentTimeMillis(long currentTimeMillis) { 1117 mStartTime = currentTimeMillis; 1118 mElapsedRealtime = 0L; 1119 } 1120 1121 private long currentTimeMillis() { 1122 return mStartTime + mElapsedRealtime; 1123 } 1124 1125 private void incrementCurrentTime(long duration) { 1126 mElapsedRealtime += duration; 1127 } 1128 1129 private FutureIntent mRestrictBackgroundChanged; 1130 1131 private void setRestrictBackground(boolean flag) throws Exception { 1132 // Must set expectation, otherwise NMPS will reset value to previous one. 1133 when(mNetworkManager.setDataSaverModeEnabled(flag)).thenReturn(true); 1134 mService.setRestrictBackground(flag); 1135 // Sanity check. 1136 assertEquals("restrictBackground not set", flag, mService.getRestrictBackground()); 1137 } 1138 1139 /** 1140 * Creates a mock and registers it to {@link LocalServices}. 1141 */ 1142 private static <T> T addLocalServiceMock(Class<T> clazz) { 1143 final T mock = mock(clazz); 1144 LocalServices.addService(clazz, mock); 1145 return mock; 1146 } 1147 1148 /** 1149 * Custom Mockito answer used to verify async {@link INetworkPolicyListener} calls. 1150 * 1151 * <p>Typical usage: 1152 * <pre><code> 1153 * mPolicyListener.expect().someCallback(any()); 1154 * // do something on objects under test 1155 * mPolicyListener.waitAndVerify().someCallback(eq(expectedValue)); 1156 * </code></pre> 1157 */ 1158 final class NetworkPolicyListenerAnswer implements Answer<Void> { 1159 private CountDownLatch latch; 1160 private final INetworkPolicyListener listener; 1161 1162 NetworkPolicyListenerAnswer(NetworkPolicyManagerService service) { 1163 this.listener = mock(INetworkPolicyListener.class); 1164 // RemoteCallbackList needs a binder to use as key 1165 when(listener.asBinder()).thenReturn(new Binder()); 1166 service.registerListener(listener); 1167 } 1168 1169 @Override 1170 public Void answer(InvocationOnMock invocation) throws Throwable { 1171 Log.d(TAG,"counting down on answer: " + invocation); 1172 latch.countDown(); 1173 return null; 1174 } 1175 1176 INetworkPolicyListener expect() { 1177 assertNull("expect() called before waitAndVerify()", latch); 1178 latch = new CountDownLatch(1); 1179 return doAnswer(this).when(listener); 1180 } 1181 1182 INetworkPolicyListener waitAndVerify() { 1183 assertNotNull("waitAndVerify() called before expect()", latch); 1184 try { 1185 assertTrue("callback not called in 5 seconds", latch.await(5, TimeUnit.SECONDS)); 1186 } catch (InterruptedException e) { 1187 fail("Thread interrupted before callback called"); 1188 } finally { 1189 latch = null; 1190 } 1191 return verify(listener, atLeastOnce()); 1192 } 1193 1194 INetworkPolicyListener verifyNotCalled() { 1195 return verify(listener, never()); 1196 } 1197 1198 } 1199 1200 private void setNetpolicyXml(Context context) throws Exception { 1201 mPolicyDir = context.getFilesDir(); 1202 if (mPolicyDir.exists()) { 1203 IoUtils.deleteContents(mPolicyDir); 1204 } 1205 if (!TextUtils.isEmpty(mNetpolicyXml)) { 1206 final String assetPath = NETPOLICY_DIR + "/" + mNetpolicyXml; 1207 final File netConfigFile = new File(mPolicyDir, "netpolicy.xml"); 1208 Log.d(TAG, "Creating " + netConfigFile + " from asset " + assetPath); 1209 try (final InputStream in = context.getResources().getAssets().open(assetPath); 1210 final OutputStream out = new FileOutputStream(netConfigFile)) { 1211 Streams.copy(in, out); 1212 } 1213 } 1214 } 1215 1216 /** 1217 * Annotation used to define the relative path of the {@code netpolicy.xml} file. 1218 */ 1219 @Retention(RetentionPolicy.RUNTIME) 1220 @Target(ElementType.METHOD) 1221 public @interface NetPolicyXml { 1222 1223 public String value() default ""; 1224 1225 } 1226 1227 /** 1228 * Rule used to set {@code mNetPolicyXml} according to the {@link NetPolicyXml} annotation. 1229 */ 1230 public static class NetPolicyMethodRule implements MethodRule { 1231 1232 @Override 1233 public Statement apply(Statement base, FrameworkMethod method, Object target) { 1234 for (Annotation annotation : method.getAnnotations()) { 1235 if ((annotation instanceof NetPolicyXml)) { 1236 final String path = ((NetPolicyXml) annotation).value(); 1237 if (!path.isEmpty()) { 1238 ((NetworkPolicyManagerServiceTest) target).mNetpolicyXml = path; 1239 break; 1240 } 1241 } 1242 } 1243 return base; 1244 } 1245 } 1246} 1247