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