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