NetworkPolicyManagerServiceTest.java revision 57e3d310913ff61ae63c66fcf3d7b64ab9d741a6
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 @NetPolicyXml("uidA-whitelisted-restrict-background-on.xml") 501 public void testWhitelistedAppIsNotifiedWhenBlacklisted() throws Exception { 502 // Sanity checks. 503 assertRestrictBackgroundOn(); 504 assertWhitelistUids(UID_A); 505 506 final FutureIntent futureIntent = newRestrictBackgroundChangedFuture(); 507 mService.setUidPolicy(UID_A, POLICY_REJECT_METERED_BACKGROUND); 508 assertRestrictBackgroundChangedReceived(futureIntent, PKG_NAME_A); 509 } 510 511 @Test 512 @NetPolicyXml("restrict-background-lists-whitelist-format.xml") 513 public void testRestrictBackgroundLists_whitelistFormat() throws Exception { 514 restrictBackgroundListsTest(); 515 } 516 517 @Test 518 @NetPolicyXml("restrict-background-lists-uid-policy-format.xml") 519 public void testRestrictBackgroundLists_uidPolicyFormat() throws Exception { 520 restrictBackgroundListsTest(); 521 } 522 523 private void restrictBackgroundListsTest() throws Exception { 524 // UIds that are whitelisted. 525 assertWhitelistUids(UID_A, UID_B, UID_C); 526 assertUidPolicy(UID_A, POLICY_ALLOW_METERED_BACKGROUND); 527 assertUidPolicy(UID_B, POLICY_ALLOW_METERED_BACKGROUND); 528 assertUidPolicy(UID_C, POLICY_ALLOW_METERED_BACKGROUND); 529 530 // UIDs that are blacklisted. 531 assertUidPolicy(UID_D, POLICY_NONE); 532 assertUidPolicy(UID_E, POLICY_REJECT_METERED_BACKGROUND); 533 534 // UIDS that have legacy policies. 535 assertUidPolicy(UID_F, 2); // POLICY_ALLOW_BACKGROUND_BATTERY_SAVE 536 537 // Remove whitelist. 538 mService.setUidPolicy(UID_A, POLICY_NONE); 539 assertUidPolicy(UID_A, POLICY_NONE); 540 assertWhitelistUids(UID_B, UID_C); 541 542 // Add whitelist when blacklisted. 543 mService.setUidPolicy(UID_E, POLICY_ALLOW_METERED_BACKGROUND); 544 assertUidPolicy(UID_E, POLICY_ALLOW_METERED_BACKGROUND); 545 assertWhitelistUids(UID_B, UID_C, UID_E); 546 547 // Add blacklist when whitelisted. 548 mService.setUidPolicy(UID_B, POLICY_REJECT_METERED_BACKGROUND); 549 assertUidPolicy(UID_B, POLICY_REJECT_METERED_BACKGROUND); 550 assertWhitelistUids(UID_C, UID_E); 551 } 552 553 /** 554 * Tests scenario where an UID had {@code restrict-background} and {@code uid-policy} tags. 555 */ 556 @Test 557 @NetPolicyXml("restrict-background-lists-mixed-format.xml") 558 public void testRestrictBackgroundLists_mixedFormat() throws Exception { 559 assertWhitelistUids(UID_A, UID_C, UID_D); 560 assertUidPolicy(UID_A, POLICY_ALLOW_METERED_BACKGROUND); 561 assertUidPolicy(UID_B, POLICY_REJECT_METERED_BACKGROUND); // Blacklist prevails. 562 assertUidPolicy(UID_C, (POLICY_ALLOW_METERED_BACKGROUND | 2)); 563 assertUidPolicy(UID_D, POLICY_ALLOW_METERED_BACKGROUND); 564 } 565 566 @Test 567 @NetPolicyXml("uids-with-mixed-policies.xml") 568 public void testGetUidsWithPolicy() throws Exception { 569 assertContainsInAnyOrder(mService.getUidsWithPolicy(POLICY_NONE), 570 UID_A); 571 assertContainsInAnyOrder(mService.getUidsWithPolicy(POLICY_REJECT_METERED_BACKGROUND), 572 UID_B, UID_D); 573 assertContainsInAnyOrder(mService.getUidsWithPolicy(POLICY_ALLOW_METERED_BACKGROUND), 574 UID_E, UID_F); 575 // Legacy (POLICY_ALLOW_BACKGROUND_BATTERY_SAVE) 576 assertContainsInAnyOrder(mService.getUidsWithPolicy(2), 577 UID_C, UID_D, UID_F); 578 } 579 580 // NOTE: testPolicyChangeTriggersListener() and testUidForeground() are too superficial, they 581 // don't check for side-effects (like calls to NetworkManagementService) neither cover all 582 // different modes (Data Saver, Battery Saver, Doze, App idle, etc...). 583 // These scenarios are extensively tested on CTS' HostsideRestrictBackgroundNetworkTests. 584 585 @Test 586 public void testPolicyChangeTriggersListener() throws Exception { 587 mPolicyListener.expect().onRestrictBackgroundBlacklistChanged(anyInt(), anyBoolean()); 588 589 mService.setUidPolicy(APP_ID_A, POLICY_NONE); 590 mService.setUidPolicy(APP_ID_A, POLICY_REJECT_METERED_BACKGROUND); 591 592 mPolicyListener.waitAndVerify().onRestrictBackgroundBlacklistChanged(APP_ID_A, true); 593 } 594 595 @Test 596 public void testUidForeground() throws Exception { 597 // push all uids into background 598 mUidObserver.onUidStateChanged(UID_A, ActivityManager.PROCESS_STATE_SERVICE); 599 mUidObserver.onUidStateChanged(UID_B, ActivityManager.PROCESS_STATE_SERVICE); 600 assertFalse(mService.isUidForeground(UID_A)); 601 assertFalse(mService.isUidForeground(UID_B)); 602 603 // push one of the uids into foreground 604 mUidObserver.onUidStateChanged(UID_A, ActivityManager.PROCESS_STATE_TOP); 605 assertTrue(mService.isUidForeground(UID_A)); 606 assertFalse(mService.isUidForeground(UID_B)); 607 608 // and swap another uid into foreground 609 mUidObserver.onUidStateChanged(UID_A, ActivityManager.PROCESS_STATE_SERVICE); 610 mUidObserver.onUidStateChanged(UID_B, ActivityManager.PROCESS_STATE_TOP); 611 assertFalse(mService.isUidForeground(UID_A)); 612 assertTrue(mService.isUidForeground(UID_B)); 613 } 614 615 @Test 616 public void testLastCycleBoundaryThisMonth() throws Exception { 617 // assume cycle day of "5th", which should be in same month 618 final long currentTime = parseTime("2007-11-14T00:00:00.000Z"); 619 final long expectedCycle = parseTime("2007-11-05T00:00:00.000Z"); 620 621 final NetworkPolicy policy = new NetworkPolicy( 622 sTemplateWifi, 5, TIMEZONE_UTC, 1024L, 1024L, false); 623 final long actualCycle = computeLastCycleBoundary(currentTime, policy); 624 assertTimeEquals(expectedCycle, actualCycle); 625 } 626 627 @Test 628 public void testLastCycleBoundaryLastMonth() throws Exception { 629 // assume cycle day of "20th", which should be in last month 630 final long currentTime = parseTime("2007-11-14T00:00:00.000Z"); 631 final long expectedCycle = parseTime("2007-10-20T00:00:00.000Z"); 632 633 final NetworkPolicy policy = new NetworkPolicy( 634 sTemplateWifi, 20, TIMEZONE_UTC, 1024L, 1024L, false); 635 final long actualCycle = computeLastCycleBoundary(currentTime, policy); 636 assertTimeEquals(expectedCycle, actualCycle); 637 } 638 639 @Test 640 public void testLastCycleBoundaryThisMonthFebruary() throws Exception { 641 // assume cycle day of "30th" in february; should go to january 642 final long currentTime = parseTime("2007-02-14T00:00:00.000Z"); 643 final long expectedCycle = parseTime("2007-01-30T00:00:00.000Z"); 644 645 final NetworkPolicy policy = new NetworkPolicy( 646 sTemplateWifi, 30, TIMEZONE_UTC, 1024L, 1024L, false); 647 final long actualCycle = computeLastCycleBoundary(currentTime, policy); 648 assertTimeEquals(expectedCycle, actualCycle); 649 } 650 651 @Test 652 public void testLastCycleBoundaryLastMonthFebruary() throws Exception { 653 // assume cycle day of "30th" in february, which should clamp 654 final long currentTime = parseTime("2007-03-14T00:00:00.000Z"); 655 final long expectedCycle = parseTime("2007-02-28T23:59:59.000Z"); 656 657 final NetworkPolicy policy = new NetworkPolicy( 658 sTemplateWifi, 30, TIMEZONE_UTC, 1024L, 1024L, false); 659 final long actualCycle = computeLastCycleBoundary(currentTime, policy); 660 assertTimeEquals(expectedCycle, actualCycle); 661 } 662 663 @Test 664 public void testCycleBoundaryLeapYear() throws Exception { 665 final NetworkPolicy policy = new NetworkPolicy( 666 sTemplateWifi, 29, TIMEZONE_UTC, 1024L, 1024L, false); 667 668 assertTimeEquals(parseTime("2012-01-29T00:00:00.000Z"), 669 computeNextCycleBoundary(parseTime("2012-01-14T00:00:00.000Z"), policy)); 670 assertTimeEquals(parseTime("2012-02-29T00:00:00.000Z"), 671 computeNextCycleBoundary(parseTime("2012-02-14T00:00:00.000Z"), policy)); 672 assertTimeEquals(parseTime("2012-02-29T00:00:00.000Z"), 673 computeLastCycleBoundary(parseTime("2012-03-14T00:00:00.000Z"), policy)); 674 assertTimeEquals(parseTime("2012-03-29T00:00:00.000Z"), 675 computeNextCycleBoundary(parseTime("2012-03-14T00:00:00.000Z"), policy)); 676 677 assertTimeEquals(parseTime("2007-01-29T00:00:00.000Z"), 678 computeNextCycleBoundary(parseTime("2007-01-14T00:00:00.000Z"), policy)); 679 assertTimeEquals(parseTime("2007-02-28T23:59:59.000Z"), 680 computeNextCycleBoundary(parseTime("2007-02-14T00:00:00.000Z"), policy)); 681 assertTimeEquals(parseTime("2007-02-28T23:59:59.000Z"), 682 computeLastCycleBoundary(parseTime("2007-03-14T00:00:00.000Z"), policy)); 683 assertTimeEquals(parseTime("2007-03-29T00:00:00.000Z"), 684 computeNextCycleBoundary(parseTime("2007-03-14T00:00:00.000Z"), policy)); 685 } 686 687 @Test 688 public void testNextCycleTimezoneAfterUtc() throws Exception { 689 // US/Central is UTC-6 690 final NetworkPolicy policy = new NetworkPolicy( 691 sTemplateWifi, 10, "US/Central", 1024L, 1024L, false); 692 assertTimeEquals(parseTime("2012-01-10T06:00:00.000Z"), 693 computeNextCycleBoundary(parseTime("2012-01-05T00:00:00.000Z"), policy)); 694 } 695 696 @Test 697 public void testNextCycleTimezoneBeforeUtc() throws Exception { 698 // Israel is UTC+2 699 final NetworkPolicy policy = new NetworkPolicy( 700 sTemplateWifi, 10, "Israel", 1024L, 1024L, false); 701 assertTimeEquals(parseTime("2012-01-09T22:00:00.000Z"), 702 computeNextCycleBoundary(parseTime("2012-01-05T00:00:00.000Z"), policy)); 703 } 704 705 @Test 706 public void testNextCycleSane() throws Exception { 707 final NetworkPolicy policy = new NetworkPolicy( 708 sTemplateWifi, 31, TIMEZONE_UTC, WARNING_DISABLED, LIMIT_DISABLED, false); 709 final LinkedHashSet<Long> seen = new LinkedHashSet<Long>(); 710 711 // walk forwards, ensuring that cycle boundaries don't get stuck 712 long currentCycle = computeNextCycleBoundary(parseTime("2011-08-01T00:00:00.000Z"), policy); 713 for (int i = 0; i < 128; i++) { 714 long nextCycle = computeNextCycleBoundary(currentCycle, policy); 715 assertEqualsFuzzy(DAY_IN_MILLIS * 30, nextCycle - currentCycle, DAY_IN_MILLIS * 3); 716 assertUnique(seen, nextCycle); 717 currentCycle = nextCycle; 718 } 719 } 720 721 @Test 722 public void testLastCycleSane() throws Exception { 723 final NetworkPolicy policy = new NetworkPolicy( 724 sTemplateWifi, 31, TIMEZONE_UTC, WARNING_DISABLED, LIMIT_DISABLED, false); 725 final LinkedHashSet<Long> seen = new LinkedHashSet<Long>(); 726 727 // walk backwards, ensuring that cycle boundaries look sane 728 long currentCycle = computeLastCycleBoundary(parseTime("2011-08-04T00:00:00.000Z"), policy); 729 for (int i = 0; i < 128; i++) { 730 long lastCycle = computeLastCycleBoundary(currentCycle, policy); 731 assertEqualsFuzzy(DAY_IN_MILLIS * 30, currentCycle - lastCycle, DAY_IN_MILLIS * 3); 732 assertUnique(seen, lastCycle); 733 currentCycle = lastCycle; 734 } 735 } 736 737 @Test 738 public void testCycleTodayJanuary() throws Exception { 739 final NetworkPolicy policy = new NetworkPolicy( 740 sTemplateWifi, 14, "US/Pacific", 1024L, 1024L, false); 741 742 assertTimeEquals(parseTime("2013-01-14T00:00:00.000-08:00"), 743 computeNextCycleBoundary(parseTime("2013-01-13T23:59:59.000-08:00"), policy)); 744 assertTimeEquals(parseTime("2013-02-14T00:00:00.000-08:00"), 745 computeNextCycleBoundary(parseTime("2013-01-14T00:00:01.000-08:00"), policy)); 746 assertTimeEquals(parseTime("2013-02-14T00:00:00.000-08:00"), 747 computeNextCycleBoundary(parseTime("2013-01-14T15:11:00.000-08:00"), policy)); 748 749 assertTimeEquals(parseTime("2012-12-14T00:00:00.000-08:00"), 750 computeLastCycleBoundary(parseTime("2013-01-13T23:59:59.000-08:00"), policy)); 751 assertTimeEquals(parseTime("2013-01-14T00:00:00.000-08:00"), 752 computeLastCycleBoundary(parseTime("2013-01-14T00:00:01.000-08:00"), policy)); 753 assertTimeEquals(parseTime("2013-01-14T00:00:00.000-08:00"), 754 computeLastCycleBoundary(parseTime("2013-01-14T15:11:00.000-08:00"), policy)); 755 } 756 757 @Test 758 public void testLastCycleBoundaryDST() throws Exception { 759 final long currentTime = parseTime("1989-01-02T07:30:00.000"); 760 final long expectedCycle = parseTime("1988-12-03T02:00:00.000Z"); 761 762 final NetworkPolicy policy = new NetworkPolicy( 763 sTemplateWifi, 3, "America/Argentina/Buenos_Aires", 1024L, 1024L, false); 764 final long actualCycle = computeLastCycleBoundary(currentTime, policy); 765 assertTimeEquals(expectedCycle, actualCycle); 766 } 767 768 @Test 769 public void testNetworkPolicyAppliedCycleLastMonth() throws Exception { 770 NetworkState[] state = null; 771 NetworkStats stats = null; 772 773 final long TIME_FEB_15 = 1171497600000L; 774 final long TIME_MAR_10 = 1173484800000L; 775 final int CYCLE_DAY = 15; 776 777 setCurrentTimeMillis(TIME_MAR_10); 778 779 // first, pretend that wifi network comes online. no policy active, 780 // which means we shouldn't push limit to interface. 781 state = new NetworkState[] { buildWifi() }; 782 when(mConnManager.getAllNetworkState()).thenReturn(state); 783 expectCurrentTime(); 784 785 mPolicyListener.expect().onMeteredIfacesChanged(any()); 786 mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION)); 787 mPolicyListener.waitAndVerify().onMeteredIfacesChanged(any()); 788 789 // now change cycle to be on 15th, and test in early march, to verify we 790 // pick cycle day in previous month. 791 when(mConnManager.getAllNetworkState()).thenReturn(state); 792 expectCurrentTime(); 793 794 // pretend that 512 bytes total have happened 795 stats = new NetworkStats(getElapsedRealtime(), 1) 796 .addIfaceValues(TEST_IFACE, 256L, 2L, 256L, 2L); 797 when(mStatsService.getNetworkTotalBytes(sTemplateWifi, TIME_FEB_15, TIME_MAR_10)) 798 .thenReturn(stats.getTotalBytes()); 799 800 mPolicyListener.expect().onMeteredIfacesChanged(any()); 801 setNetworkPolicies(new NetworkPolicy( 802 sTemplateWifi, CYCLE_DAY, TIMEZONE_UTC, 1 * MB_IN_BYTES, 2 * MB_IN_BYTES, false)); 803 mPolicyListener.waitAndVerify().onMeteredIfacesChanged(eq(new String[]{TEST_IFACE})); 804 805 // TODO: consider making strongly ordered mock 806 verifyPolicyDataEnable(TYPE_WIFI, true); 807 verifyRemoveInterfaceQuota(TEST_IFACE); 808 verifySetInterfaceQuota(TEST_IFACE, (2 * MB_IN_BYTES) - 512); 809 } 810 811 @Test 812 public void testOverWarningLimitNotification() throws Exception { 813 NetworkState[] state = null; 814 NetworkStats stats = null; 815 Future<String> tagFuture = null; 816 817 final long TIME_FEB_15 = 1171497600000L; 818 final long TIME_MAR_10 = 1173484800000L; 819 final int CYCLE_DAY = 15; 820 821 setCurrentTimeMillis(TIME_MAR_10); 822 823 // assign wifi policy 824 state = new NetworkState[] {}; 825 stats = new NetworkStats(getElapsedRealtime(), 1) 826 .addIfaceValues(TEST_IFACE, 0L, 0L, 0L, 0L); 827 828 { 829 expectCurrentTime(); 830 when(mConnManager.getAllNetworkState()).thenReturn(state); 831 when(mStatsService.getNetworkTotalBytes(sTemplateWifi, TIME_FEB_15, 832 currentTimeMillis())).thenReturn(stats.getTotalBytes()); 833 834 mPolicyListener.expect().onMeteredIfacesChanged(any()); 835 setNetworkPolicies(new NetworkPolicy(sTemplateWifi, CYCLE_DAY, TIMEZONE_UTC, 1 836 * MB_IN_BYTES, 2 * MB_IN_BYTES, false)); 837 mPolicyListener.waitAndVerify().onMeteredIfacesChanged(any()); 838 verifyPolicyDataEnable(TYPE_WIFI, true); 839 } 840 841 // bring up wifi network 842 incrementCurrentTime(MINUTE_IN_MILLIS); 843 state = new NetworkState[] { buildWifi() }; 844 stats = new NetworkStats(getElapsedRealtime(), 1) 845 .addIfaceValues(TEST_IFACE, 0L, 0L, 0L, 0L); 846 847 { 848 expectCurrentTime(); 849 when(mConnManager.getAllNetworkState()).thenReturn(state); 850 when(mStatsService.getNetworkTotalBytes(sTemplateWifi, TIME_FEB_15, 851 currentTimeMillis())).thenReturn(stats.getTotalBytes()); 852 853 mPolicyListener.expect().onMeteredIfacesChanged(any()); 854 mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION)); 855 mPolicyListener.waitAndVerify().onMeteredIfacesChanged(eq(new String[]{TEST_IFACE})); 856 857 verifyPolicyDataEnable(TYPE_WIFI, true); 858 verifyRemoveInterfaceQuota(TEST_IFACE); 859 verifySetInterfaceQuota(TEST_IFACE, 2 * MB_IN_BYTES); 860 } 861 862 // go over warning, which should kick notification 863 incrementCurrentTime(MINUTE_IN_MILLIS); 864 stats = new NetworkStats(getElapsedRealtime(), 1) 865 .addIfaceValues(TEST_IFACE, 1536 * KB_IN_BYTES, 15L, 0L, 0L); 866 867 { 868 expectCurrentTime(); 869 when(mStatsService.getNetworkTotalBytes(sTemplateWifi, TIME_FEB_15, 870 currentTimeMillis())).thenReturn(stats.getTotalBytes()); 871 tagFuture = expectEnqueueNotification(); 872 873 mNetworkObserver.limitReached(null, TEST_IFACE); 874 875 assertNotificationType(TYPE_WARNING, tagFuture.get()); 876 verifyPolicyDataEnable(TYPE_WIFI, true); 877 878 } 879 880 // go over limit, which should kick notification and dialog 881 incrementCurrentTime(MINUTE_IN_MILLIS); 882 stats = new NetworkStats(getElapsedRealtime(), 1) 883 .addIfaceValues(TEST_IFACE, 5 * MB_IN_BYTES, 512L, 0L, 0L); 884 885 { 886 expectCurrentTime(); 887 when(mStatsService.getNetworkTotalBytes(sTemplateWifi, TIME_FEB_15, 888 currentTimeMillis())).thenReturn(stats.getTotalBytes()); 889 tagFuture = expectEnqueueNotification(); 890 891 mNetworkObserver.limitReached(null, TEST_IFACE); 892 893 assertNotificationType(TYPE_LIMIT, tagFuture.get()); 894 verifyPolicyDataEnable(TYPE_WIFI, false); 895 } 896 897 // now snooze policy, which should remove quota 898 incrementCurrentTime(MINUTE_IN_MILLIS); 899 900 { 901 expectCurrentTime(); 902 when(mConnManager.getAllNetworkState()).thenReturn(state); 903 when(mStatsService.getNetworkTotalBytes(sTemplateWifi, TIME_FEB_15, 904 currentTimeMillis())).thenReturn(stats.getTotalBytes()); 905 tagFuture = expectEnqueueNotification(); 906 907 mPolicyListener.expect().onMeteredIfacesChanged(any()); 908 mService.snoozeLimit(sTemplateWifi); 909 mPolicyListener.waitAndVerify().onMeteredIfacesChanged(eq(new String[]{TEST_IFACE})); 910 911 assertNotificationType(TYPE_LIMIT_SNOOZED, tagFuture.get()); 912 // snoozed interface still has high quota so background data is 913 // still restricted. 914 verifyRemoveInterfaceQuota(TEST_IFACE); 915 verifySetInterfaceQuota(TEST_IFACE, Long.MAX_VALUE); 916 verifyPolicyDataEnable(TYPE_WIFI, true); 917 } 918 } 919 920 @Test 921 public void testMeteredNetworkWithoutLimit() throws Exception { 922 NetworkState[] state = null; 923 NetworkStats stats = null; 924 925 final long TIME_FEB_15 = 1171497600000L; 926 final long TIME_MAR_10 = 1173484800000L; 927 final int CYCLE_DAY = 15; 928 929 setCurrentTimeMillis(TIME_MAR_10); 930 931 // bring up wifi network with metered policy 932 state = new NetworkState[] { buildWifi() }; 933 stats = new NetworkStats(getElapsedRealtime(), 1) 934 .addIfaceValues(TEST_IFACE, 0L, 0L, 0L, 0L); 935 936 { 937 expectCurrentTime(); 938 when(mConnManager.getAllNetworkState()).thenReturn(state); 939 when(mStatsService.getNetworkTotalBytes(sTemplateWifi, TIME_FEB_15, 940 currentTimeMillis())).thenReturn(stats.getTotalBytes()); 941 942 mPolicyListener.expect().onMeteredIfacesChanged(any()); 943 setNetworkPolicies(new NetworkPolicy( 944 sTemplateWifi, CYCLE_DAY, TIMEZONE_UTC, WARNING_DISABLED, LIMIT_DISABLED, 945 true)); 946 mPolicyListener.waitAndVerify().onMeteredIfacesChanged(eq(new String[]{TEST_IFACE})); 947 948 verifyPolicyDataEnable(TYPE_WIFI, true); 949 verifyRemoveInterfaceQuota(TEST_IFACE); 950 verifySetInterfaceQuota(TEST_IFACE, Long.MAX_VALUE); 951 } 952 } 953 954 private static long parseTime(String time) { 955 final Time result = new Time(); 956 result.parse3339(time); 957 return result.toMillis(true); 958 } 959 960 private void setNetworkPolicies(NetworkPolicy... policies) { 961 mService.setNetworkPolicies(policies); 962 } 963 964 private static NetworkState buildWifi() { 965 final NetworkInfo info = new NetworkInfo(TYPE_WIFI, 0, null, null); 966 info.setDetailedState(DetailedState.CONNECTED, null, null); 967 final LinkProperties prop = new LinkProperties(); 968 prop.setInterfaceName(TEST_IFACE); 969 return new NetworkState(info, prop, null, null, null, TEST_SSID); 970 } 971 972 private void expectCurrentTime() throws Exception { 973 when(mTime.forceRefresh()).thenReturn(false); 974 when(mTime.hasCache()).thenReturn(true); 975 when(mTime.currentTimeMillis()).thenReturn(currentTimeMillis()); 976 when(mTime.getCacheAge()).thenReturn(0L); 977 when(mTime.getCacheCertainty()).thenReturn(0L); 978 } 979 980 private Future<String> expectEnqueueNotification() throws Exception { 981 final FutureAnswer<String> futureAnswer = new FutureAnswer<String>(2); 982 doAnswer(futureAnswer).when(mNotifManager).enqueueNotificationWithTag( 983 anyString(), anyString(), anyString() /* capture here (index 2)*/, 984 anyInt(), isA(Notification.class), isA(int[].class), anyInt()); 985 return futureAnswer; 986 } 987 988 private void expectHasInternetPermission(int uid, boolean hasIt) throws Exception { 989 when(mIpm.checkUidPermission(Manifest.permission.INTERNET, uid)).thenReturn( 990 hasIt ? PackageManager.PERMISSION_GRANTED : PackageManager.PERMISSION_DENIED); 991 } 992 993 private void verifySetInterfaceQuota(String iface, long quotaBytes) throws Exception { 994 verify(mNetworkManager, atLeastOnce()).setInterfaceQuota(iface, quotaBytes); 995 } 996 997 private void verifyRemoveInterfaceQuota(String iface) throws Exception { 998 verify(mNetworkManager, atLeastOnce()).removeInterfaceQuota(iface); 999 } 1000 1001 private Future<Void> verifyPolicyDataEnable(int type, boolean enabled) throws Exception { 1002 // TODO: bring back this test 1003 return null; 1004 } 1005 1006 private void verifyAdvisePersistThreshold() throws Exception { 1007 verify(mStatsService).advisePersistThreshold(anyLong()); 1008 } 1009 1010 private static class TestAbstractFuture<T> extends AbstractFuture<T> { 1011 @Override 1012 public T get() throws InterruptedException, ExecutionException { 1013 try { 1014 return get(5, TimeUnit.SECONDS); 1015 } catch (TimeoutException e) { 1016 throw new RuntimeException(e); 1017 } 1018 } 1019 } 1020 1021 private static class FutureAnswer<T> extends TestAbstractFuture<T> implements Answer<Void> { 1022 private final int index; 1023 1024 FutureAnswer(int index) { 1025 this.index = index; 1026 } 1027 @Override 1028 public Void answer(InvocationOnMock invocation) throws Throwable { 1029 @SuppressWarnings("unchecked") 1030 T captured = (T) invocation.getArguments()[index]; 1031 set(captured); 1032 return null; 1033 } 1034 } 1035 1036 private static void assertTimeEquals(long expected, long actual) { 1037 if (expected != actual) { 1038 fail("expected " + formatTime(expected) + " but was actually " + formatTime(actual)); 1039 } 1040 } 1041 1042 private static String formatTime(long millis) { 1043 final Time time = new Time(Time.TIMEZONE_UTC); 1044 time.set(millis); 1045 return time.format3339(false); 1046 } 1047 1048 private static void assertEqualsFuzzy(long expected, long actual, long fuzzy) { 1049 final long low = expected - fuzzy; 1050 final long high = expected + fuzzy; 1051 if (actual < low || actual > high) { 1052 fail("value " + actual + " is outside [" + low + "," + high + "]"); 1053 } 1054 } 1055 1056 private static void assertUnique(LinkedHashSet<Long> seen, Long value) { 1057 if (!seen.add(value)) { 1058 fail("found duplicate time " + value + " in series " + seen.toString()); 1059 } 1060 } 1061 1062 private static void assertNotificationType(int expected, String actualTag) { 1063 assertEquals("notification type mismatch for '" + actualTag +"'", 1064 Integer.toString(expected), actualTag.substring(actualTag.lastIndexOf(':') + 1)); 1065 } 1066 1067 private void assertUidPolicy(int uid, int expected) { 1068 final int actual = mService.getUidPolicy(uid); 1069 if (expected != actual) { 1070 fail("Wrong policy for UID " + uid + ": expected " + uidPoliciesToString(expected) 1071 + ", actual " + uidPoliciesToString(actual)); 1072 } 1073 } 1074 1075 private void assertWhitelistUids(int... uids) { 1076 assertContainsInAnyOrder(mService.getUidsWithPolicy(POLICY_ALLOW_METERED_BACKGROUND), uids); 1077 } 1078 1079 private void assertRestrictBackgroundOn() throws Exception { 1080 assertTrue("restrictBackground should be set", mService.getRestrictBackground()); 1081 } 1082 1083 private void assertRestrictBackgroundOff() throws Exception { 1084 assertFalse("restrictBackground should not be set", mService.getRestrictBackground()); 1085 } 1086 1087 private FutureIntent newRestrictBackgroundChangedFuture() { 1088 return mServiceContext 1089 .nextBroadcastIntent(ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED); 1090 } 1091 1092 private void assertRestrictBackgroundChangedReceived(Future<Intent> future, 1093 String expectedPackage) throws Exception { 1094 final String action = ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED; 1095 final Intent intent = future.get(5, TimeUnit.SECONDS); 1096 assertNotNull("Didn't get a " + action + "intent in 5 seconds"); 1097 assertEquals("Wrong package on " + action + " intent", expectedPackage, intent.getPackage()); 1098 } 1099 1100 // TODO: replace by Truth, Hamcrest, or a similar tool. 1101 private void assertContainsInAnyOrder(int[] actual, int...expected) { 1102 final StringBuilder errors = new StringBuilder(); 1103 if (actual.length != expected.length) { 1104 errors.append("\tsize does not match\n"); 1105 } 1106 final List<Integer> actualList = 1107 Arrays.stream(actual).boxed().collect(Collectors.<Integer>toList()); 1108 final List<Integer> expectedList = 1109 Arrays.stream(expected).boxed().collect(Collectors.<Integer>toList()); 1110 if (!actualList.containsAll(expectedList)) { 1111 errors.append("\tmissing elements on actual list\n"); 1112 } 1113 if (!expectedList.containsAll(actualList)) { 1114 errors.append("\tmissing elements on expected list\n"); 1115 } 1116 if (errors.length() > 0) { 1117 fail("assertContainsInAnyOrder(expected=" + Arrays.toString(expected) 1118 + ", actual=" + Arrays.toString(actual) +") failed: \n" + errors); 1119 } 1120 } 1121 1122 private long getElapsedRealtime() { 1123 return mElapsedRealtime; 1124 } 1125 1126 private void setCurrentTimeMillis(long currentTimeMillis) { 1127 mStartTime = currentTimeMillis; 1128 mElapsedRealtime = 0L; 1129 } 1130 1131 private long currentTimeMillis() { 1132 return mStartTime + mElapsedRealtime; 1133 } 1134 1135 private void incrementCurrentTime(long duration) { 1136 mElapsedRealtime += duration; 1137 } 1138 1139 private FutureIntent mRestrictBackgroundChanged; 1140 1141 private void setRestrictBackground(boolean flag) throws Exception { 1142 // Must set expectation, otherwise NMPS will reset value to previous one. 1143 when(mNetworkManager.setDataSaverModeEnabled(flag)).thenReturn(true); 1144 mService.setRestrictBackground(flag); 1145 // Sanity check. 1146 assertEquals("restrictBackground not set", flag, mService.getRestrictBackground()); 1147 } 1148 1149 /** 1150 * Creates a mock and registers it to {@link LocalServices}. 1151 */ 1152 private static <T> T addLocalServiceMock(Class<T> clazz) { 1153 final T mock = mock(clazz); 1154 LocalServices.addService(clazz, mock); 1155 return mock; 1156 } 1157 1158 /** 1159 * Custom Mockito answer used to verify async {@link INetworkPolicyListener} calls. 1160 * 1161 * <p>Typical usage: 1162 * <pre><code> 1163 * mPolicyListener.expect().someCallback(any()); 1164 * // do something on objects under test 1165 * mPolicyListener.waitAndVerify().someCallback(eq(expectedValue)); 1166 * </code></pre> 1167 */ 1168 final class NetworkPolicyListenerAnswer implements Answer<Void> { 1169 private CountDownLatch latch; 1170 private final INetworkPolicyListener listener; 1171 1172 NetworkPolicyListenerAnswer(NetworkPolicyManagerService service) { 1173 this.listener = mock(INetworkPolicyListener.class); 1174 // RemoteCallbackList needs a binder to use as key 1175 when(listener.asBinder()).thenReturn(new Binder()); 1176 service.registerListener(listener); 1177 } 1178 1179 @Override 1180 public Void answer(InvocationOnMock invocation) throws Throwable { 1181 Log.d(TAG,"counting down on answer: " + invocation); 1182 latch.countDown(); 1183 return null; 1184 } 1185 1186 INetworkPolicyListener expect() { 1187 assertNull("expect() called before waitAndVerify()", latch); 1188 latch = new CountDownLatch(1); 1189 return doAnswer(this).when(listener); 1190 } 1191 1192 INetworkPolicyListener waitAndVerify() { 1193 assertNotNull("waitAndVerify() called before expect()", latch); 1194 try { 1195 assertTrue("callback not called in 5 seconds", latch.await(5, TimeUnit.SECONDS)); 1196 } catch (InterruptedException e) { 1197 fail("Thread interrupted before callback called"); 1198 } finally { 1199 latch = null; 1200 } 1201 return verify(listener, atLeastOnce()); 1202 } 1203 1204 INetworkPolicyListener verifyNotCalled() { 1205 return verify(listener, never()); 1206 } 1207 1208 } 1209 1210 private void setNetpolicyXml(Context context) throws Exception { 1211 mPolicyDir = context.getFilesDir(); 1212 if (mPolicyDir.exists()) { 1213 IoUtils.deleteContents(mPolicyDir); 1214 } 1215 if (!TextUtils.isEmpty(mNetpolicyXml)) { 1216 final String assetPath = NETPOLICY_DIR + "/" + mNetpolicyXml; 1217 final File netConfigFile = new File(mPolicyDir, "netpolicy.xml"); 1218 Log.d(TAG, "Creating " + netConfigFile + " from asset " + assetPath); 1219 try (final InputStream in = context.getResources().getAssets().open(assetPath); 1220 final OutputStream out = new FileOutputStream(netConfigFile)) { 1221 Streams.copy(in, out); 1222 } 1223 } 1224 } 1225 1226 /** 1227 * Annotation used to define the relative path of the {@code netpolicy.xml} file. 1228 */ 1229 @Retention(RetentionPolicy.RUNTIME) 1230 @Target(ElementType.METHOD) 1231 public @interface NetPolicyXml { 1232 1233 public String value() default ""; 1234 1235 } 1236 1237 /** 1238 * Rule used to set {@code mNetPolicyXml} according to the {@link NetPolicyXml} annotation. 1239 */ 1240 public static class NetPolicyMethodRule implements MethodRule { 1241 1242 @Override 1243 public Statement apply(Statement base, FrameworkMethod method, Object target) { 1244 for (Annotation annotation : method.getAnnotations()) { 1245 if ((annotation instanceof NetPolicyXml)) { 1246 final String path = ((NetPolicyXml) annotation).value(); 1247 if (!path.isEmpty()) { 1248 ((NetworkPolicyManagerServiceTest) target).mNetpolicyXml = path; 1249 break; 1250 } 1251 } 1252 } 1253 return base; 1254 } 1255 } 1256} 1257