Home | History | Annotate | Download | only in server
      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 
     17 package com.android.server;
     18 
     19 import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
     20 import static android.net.ConnectivityManager.TYPE_WIFI;
     21 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING;
     22 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
     23 import static android.net.NetworkPolicy.LIMIT_DISABLED;
     24 import static android.net.NetworkPolicy.SNOOZE_NEVER;
     25 import static android.net.NetworkPolicy.WARNING_DISABLED;
     26 import static android.net.NetworkPolicyManager.POLICY_ALLOW_METERED_BACKGROUND;
     27 import static android.net.NetworkPolicyManager.POLICY_NONE;
     28 import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND;
     29 import static android.net.NetworkPolicyManager.uidPoliciesToString;
     30 import static android.net.NetworkStats.IFACE_ALL;
     31 import static android.net.NetworkStats.SET_ALL;
     32 import static android.net.NetworkStats.TAG_ALL;
     33 import static android.net.NetworkTemplate.buildTemplateMobileAll;
     34 import static android.net.NetworkTemplate.buildTemplateWifi;
     35 import static android.net.TrafficStats.MB_IN_BYTES;
     36 import static android.telephony.CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED;
     37 import static android.telephony.CarrierConfigManager.DATA_CYCLE_THRESHOLD_DISABLED;
     38 import static android.telephony.CarrierConfigManager.DATA_CYCLE_USE_PLATFORM_DEFAULT;
     39 import static android.telephony.CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG;
     40 import static android.telephony.CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG;
     41 import static android.telephony.CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT;
     42 import static android.telephony.SubscriptionPlan.BYTES_UNLIMITED;
     43 import static android.telephony.SubscriptionPlan.LIMIT_BEHAVIOR_DISABLED;
     44 import static android.text.format.Time.TIMEZONE_UTC;
     45 
     46 import static com.android.server.net.NetworkPolicyManagerInternal.QUOTA_TYPE_JOBS;
     47 import static com.android.server.net.NetworkPolicyManagerInternal.QUOTA_TYPE_MULTIPATH;
     48 import static com.android.server.net.NetworkPolicyManagerService.OPPORTUNISTIC_QUOTA_UNKNOWN;
     49 import static com.android.server.net.NetworkPolicyManagerService.TYPE_LIMIT;
     50 import static com.android.server.net.NetworkPolicyManagerService.TYPE_LIMIT_SNOOZED;
     51 import static com.android.server.net.NetworkPolicyManagerService.TYPE_RAPID;
     52 import static com.android.server.net.NetworkPolicyManagerService.TYPE_WARNING;
     53 
     54 import static org.junit.Assert.assertEquals;
     55 import static org.junit.Assert.assertFalse;
     56 import static org.junit.Assert.assertNotNull;
     57 import static org.junit.Assert.assertNull;
     58 import static org.junit.Assert.assertTrue;
     59 import static org.junit.Assert.fail;
     60 import static org.mockito.ArgumentMatchers.any;
     61 import static org.mockito.ArgumentMatchers.anyBoolean;
     62 import static org.mockito.ArgumentMatchers.anyInt;
     63 import static org.mockito.ArgumentMatchers.anyLong;
     64 import static org.mockito.ArgumentMatchers.anyString;
     65 import static org.mockito.ArgumentMatchers.eq;
     66 import static org.mockito.ArgumentMatchers.isA;
     67 import static org.mockito.ArgumentMatchers.isNull;
     68 import static org.mockito.Mockito.atLeast;
     69 import static org.mockito.Mockito.atLeastOnce;
     70 import static org.mockito.Mockito.doAnswer;
     71 import static org.mockito.Mockito.doNothing;
     72 import static org.mockito.Mockito.mock;
     73 import static org.mockito.Mockito.never;
     74 import static org.mockito.Mockito.reset;
     75 import static org.mockito.Mockito.verify;
     76 import static org.mockito.Mockito.when;
     77 
     78 import android.Manifest;
     79 import android.app.ActivityManager;
     80 import android.app.ActivityManagerInternal;
     81 import android.app.IActivityManager;
     82 import android.app.IUidObserver;
     83 import android.app.Notification;
     84 import android.app.NotificationManager;
     85 import android.app.usage.UsageStatsManagerInternal;
     86 import android.content.Context;
     87 import android.content.Intent;
     88 import android.content.pm.ApplicationInfo;
     89 import android.content.pm.IPackageManager;
     90 import android.content.pm.PackageInfo;
     91 import android.content.pm.PackageManager;
     92 import android.content.pm.Signature;
     93 import android.net.ConnectivityManager;
     94 import android.net.IConnectivityManager;
     95 import android.net.INetworkManagementEventObserver;
     96 import android.net.INetworkPolicyListener;
     97 import android.net.LinkProperties;
     98 import android.net.Network;
     99 import android.net.NetworkCapabilities;
    100 import android.net.NetworkInfo;
    101 import android.net.NetworkInfo.DetailedState;
    102 import android.net.NetworkPolicy;
    103 import android.net.NetworkState;
    104 import android.net.NetworkStats;
    105 import android.net.NetworkStatsHistory;
    106 import android.net.NetworkTemplate;
    107 import android.net.StringNetworkSpecifier;
    108 import android.os.Binder;
    109 import android.os.INetworkManagementService;
    110 import android.os.PersistableBundle;
    111 import android.os.PowerManagerInternal;
    112 import android.os.PowerSaveState;
    113 import android.os.RemoteException;
    114 import android.os.SimpleClock;
    115 import android.os.SystemClock;
    116 import android.os.UserHandle;
    117 import android.support.test.InstrumentationRegistry;
    118 import android.support.test.runner.AndroidJUnit4;
    119 import android.telephony.CarrierConfigManager;
    120 import android.telephony.SubscriptionManager;
    121 import android.telephony.SubscriptionPlan;
    122 import android.telephony.TelephonyManager;
    123 import android.test.suitebuilder.annotation.MediumTest;
    124 import android.text.TextUtils;
    125 import android.text.format.Time;
    126 import android.util.DataUnit;
    127 import android.util.Log;
    128 import android.util.Range;
    129 import android.util.RecurrenceRule;
    130 
    131 import com.android.internal.telephony.PhoneConstants;
    132 import com.android.internal.util.test.BroadcastInterceptingContext;
    133 import com.android.internal.util.test.BroadcastInterceptingContext.FutureIntent;
    134 import com.android.server.net.NetworkPolicyManagerInternal;
    135 import com.android.server.net.NetworkPolicyManagerService;
    136 import com.android.server.net.NetworkStatsManagerInternal;
    137 
    138 import libcore.io.IoUtils;
    139 import libcore.io.Streams;
    140 
    141 import com.google.common.util.concurrent.AbstractFuture;
    142 
    143 import org.junit.After;
    144 import org.junit.Before;
    145 import org.junit.Rule;
    146 import org.junit.Test;
    147 import org.junit.rules.MethodRule;
    148 import org.junit.runner.RunWith;
    149 import org.junit.runners.model.FrameworkMethod;
    150 import org.junit.runners.model.Statement;
    151 import org.mockito.ArgumentCaptor;
    152 import org.mockito.Mock;
    153 import org.mockito.MockitoAnnotations;
    154 import org.mockito.invocation.InvocationOnMock;
    155 import org.mockito.stubbing.Answer;
    156 
    157 import java.io.File;
    158 import java.io.FileOutputStream;
    159 import java.io.InputStream;
    160 import java.io.OutputStream;
    161 import java.lang.annotation.Annotation;
    162 import java.lang.annotation.ElementType;
    163 import java.lang.annotation.Retention;
    164 import java.lang.annotation.RetentionPolicy;
    165 import java.lang.annotation.Target;
    166 import java.time.Clock;
    167 import java.time.Instant;
    168 import java.time.Period;
    169 import java.time.ZoneId;
    170 import java.time.ZoneOffset;
    171 import java.time.ZonedDateTime;
    172 import java.util.Arrays;
    173 import java.util.Calendar;
    174 import java.util.Iterator;
    175 import java.util.LinkedHashSet;
    176 import java.util.List;
    177 import java.util.concurrent.CountDownLatch;
    178 import java.util.concurrent.ExecutionException;
    179 import java.util.concurrent.Future;
    180 import java.util.concurrent.TimeUnit;
    181 import java.util.concurrent.TimeoutException;
    182 import java.util.stream.Collectors;
    183 
    184 /**
    185  * Tests for {@link NetworkPolicyManagerService}.
    186  *
    187  * <p>Typical usage:
    188  *
    189  * <pre><code>
    190     m -j32 FrameworksServicesTests && adb install -r -g \
    191     ${ANDROID_PRODUCT_OUT}/data/app/FrameworksServicesTests/FrameworksServicesTests.apk && \
    192     adb shell am instrument -e class "com.android.server.NetworkPolicyManagerServiceTest" -w \
    193     "com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner"
    194  * </code></pre>
    195  */
    196 @RunWith(AndroidJUnit4.class)
    197 @MediumTest
    198 public class NetworkPolicyManagerServiceTest {
    199     private static final String TAG = "NetworkPolicyManagerServiceTest";
    200 
    201     private static final long TEST_START = 1194220800000L;
    202     private static final String TEST_IFACE = "test0";
    203     private static final String TEST_SSID = "AndroidAP";
    204     private static final String TEST_IMSI = "310210";
    205     private static final int TEST_SUB_ID = 42;
    206     private static final int TEST_NET_ID = 24;
    207 
    208     private static NetworkTemplate sTemplateWifi = buildTemplateWifi(TEST_SSID);
    209     private static NetworkTemplate sTemplateMobileAll = buildTemplateMobileAll(TEST_IMSI);
    210 
    211     /**
    212      * Path on assets where files used by {@link NetPolicyXml} are located.
    213      */
    214     private static final String NETPOLICY_DIR = "NetworkPolicyManagerServiceTest/netpolicy";
    215 
    216     private BroadcastInterceptingContext mServiceContext;
    217     private File mPolicyDir;
    218 
    219     /**
    220      * Relative path of the XML file that will be used as {@code netpolicy.xml}.
    221      *
    222      * <p>Typically set through a {@link NetPolicyXml} annotation in the test method.
    223      */
    224     private String mNetpolicyXml;
    225 
    226     private @Mock IActivityManager mActivityManager;
    227     private @Mock INetworkManagementService mNetworkManager;
    228     private @Mock IConnectivityManager mConnManager;
    229     private @Mock ConnectivityManager mConnectivityManager;
    230     private @Mock NotificationManager mNotifManager;
    231     private @Mock PackageManager mPackageManager;
    232     private @Mock IPackageManager mIpm;
    233     private @Mock SubscriptionManager mSubscriptionManager;
    234     private @Mock CarrierConfigManager mCarrierConfigManager;
    235     private @Mock TelephonyManager mTelephonyManager;
    236 
    237     private ArgumentCaptor<ConnectivityManager.NetworkCallback> mNetworkCallbackCaptor =
    238             ArgumentCaptor.forClass(ConnectivityManager.NetworkCallback.class);
    239 
    240     private ActivityManagerInternal mActivityManagerInternal;
    241     private NetworkStatsManagerInternal mStatsService;
    242 
    243     private IUidObserver mUidObserver;
    244     private INetworkManagementEventObserver mNetworkObserver;
    245 
    246     private NetworkPolicyListenerAnswer mPolicyListener;
    247     private NetworkPolicyManagerService mService;
    248 
    249     /**
    250      * In some of the tests while initializing NetworkPolicyManagerService,
    251      * ACTION_RESTRICT_BACKGROUND_CHANGED is broadcasted. This is for capturing that broadcast.
    252      */
    253     private FutureIntent mFutureIntent;
    254 
    255     private long mStartTime;
    256     private long mElapsedRealtime;
    257 
    258     private static final int USER_ID = 0;
    259     private static final int FAKE_SUB_ID = 3737373;
    260     private static final String FAKE_SUBSCRIBER_ID = "FAKE_SUB_ID";
    261     private static final int DEFAULT_CYCLE_DAY = 1;
    262     private static final int INVALID_CARRIER_CONFIG_VALUE = -9999;
    263     private long mDefaultWarningBytes; // filled in with the actual default before tests are run
    264     private long mDefaultLimitBytes; // filled in with the actual default before tests are run
    265 
    266     private static final int APP_ID_A = android.os.Process.FIRST_APPLICATION_UID + 4;
    267     private static final int APP_ID_B = android.os.Process.FIRST_APPLICATION_UID + 8;
    268     private static final int APP_ID_C = android.os.Process.FIRST_APPLICATION_UID + 15;
    269     private static final int APP_ID_D = android.os.Process.FIRST_APPLICATION_UID + 16;
    270     private static final int APP_ID_E = android.os.Process.FIRST_APPLICATION_UID + 23;
    271     private static final int APP_ID_F = android.os.Process.FIRST_APPLICATION_UID + 42;
    272 
    273     private static final int UID_A = UserHandle.getUid(USER_ID, APP_ID_A);
    274     private static final int UID_B = UserHandle.getUid(USER_ID, APP_ID_B);
    275     private static final int UID_C = UserHandle.getUid(USER_ID, APP_ID_C);
    276     private static final int UID_D = UserHandle.getUid(USER_ID, APP_ID_D);
    277     private static final int UID_E = UserHandle.getUid(USER_ID, APP_ID_E);
    278     private static final int UID_F = UserHandle.getUid(USER_ID, APP_ID_F);
    279 
    280     private static final String PKG_NAME_A = "name.is.A,pkg.A";
    281     private static final String PKG_NAME_B = "name.is.B,pkg.B";
    282     private static final String PKG_NAME_C = "name.is.C,pkg.C";
    283 
    284     public final @Rule NetPolicyMethodRule mNetPolicyXmlRule = new NetPolicyMethodRule();
    285 
    286     private final Clock mClock = new SimpleClock(ZoneOffset.UTC) {
    287         @Override
    288         public long millis() {
    289             return currentTimeMillis();
    290         }
    291     };
    292 
    293     private void registerLocalServices() {
    294         addLocalServiceMock(DeviceIdleController.LocalService.class);
    295 
    296         final UsageStatsManagerInternal usageStats =
    297                 addLocalServiceMock(UsageStatsManagerInternal.class);
    298         when(usageStats.getIdleUidsForUser(anyInt())).thenReturn(new int[]{});
    299 
    300         mActivityManagerInternal = addLocalServiceMock(ActivityManagerInternal.class);
    301 
    302         final PowerSaveState state = new PowerSaveState.Builder()
    303                 .setBatterySaverEnabled(false).build();
    304         final PowerManagerInternal pmInternal = addLocalServiceMock(PowerManagerInternal.class);
    305         when(pmInternal.getLowPowerState(anyInt())).thenReturn(state);
    306 
    307         mStatsService = addLocalServiceMock(NetworkStatsManagerInternal.class);
    308     }
    309 
    310     @Before
    311     public void callSystemReady() throws Exception {
    312         MockitoAnnotations.initMocks(this);
    313 
    314         final Context context = InstrumentationRegistry.getContext();
    315 
    316         setCurrentTimeMillis(TEST_START);
    317 
    318         registerLocalServices();
    319         // Intercept various broadcasts, and pretend that uids have packages.
    320         // Also return mock service instances for a few critical services.
    321         mServiceContext = new BroadcastInterceptingContext(context) {
    322             @Override
    323             public PackageManager getPackageManager() {
    324                 return mPackageManager;
    325             }
    326 
    327             @Override
    328             public void startActivity(Intent intent) {
    329                 // ignored
    330             }
    331 
    332             @Override
    333             public Object getSystemService(String name) {
    334                 switch (name) {
    335                     case Context.TELEPHONY_SUBSCRIPTION_SERVICE:
    336                         return mSubscriptionManager;
    337                     case Context.CARRIER_CONFIG_SERVICE:
    338                         return mCarrierConfigManager;
    339                     case Context.TELEPHONY_SERVICE:
    340                         return mTelephonyManager;
    341                     case Context.NOTIFICATION_SERVICE:
    342                         return mNotifManager;
    343                     case Context.CONNECTIVITY_SERVICE:
    344                         return mConnectivityManager;
    345                     default:
    346                         return super.getSystemService(name);
    347                 }
    348             }
    349 
    350             @Override
    351             public void enforceCallingOrSelfPermission(String permission, String message) {
    352                 // Assume that we're AID_SYSTEM
    353             }
    354         };
    355 
    356         setNetpolicyXml(context);
    357 
    358         doAnswer(new Answer<Void>() {
    359 
    360             @Override
    361             public Void answer(InvocationOnMock invocation) throws Throwable {
    362                 mUidObserver = (IUidObserver) invocation.getArguments()[0];
    363                 Log.d(TAG, "set mUidObserver to " + mUidObserver);
    364                 return null;
    365             }
    366         }).when(mActivityManager).registerUidObserver(any(), anyInt(),
    367                 eq(ActivityManager.PROCESS_STATE_UNKNOWN), isNull(String.class));
    368 
    369         mFutureIntent = newRestrictBackgroundChangedFuture();
    370         mService = new NetworkPolicyManagerService(mServiceContext, mActivityManager,
    371                 mNetworkManager, mIpm, mClock, mPolicyDir, true);
    372         mService.bindConnectivityManager(mConnManager);
    373         mPolicyListener = new NetworkPolicyListenerAnswer(mService);
    374 
    375         // Sets some common expectations.
    376         when(mPackageManager.getPackageInfo(anyString(), anyInt())).thenAnswer(
    377                 new Answer<PackageInfo>() {
    378 
    379                     @Override
    380                     public PackageInfo answer(InvocationOnMock invocation) throws Throwable {
    381                         final String packageName = (String) invocation.getArguments()[0];
    382                         final PackageInfo info = new PackageInfo();
    383                         final Signature signature;
    384                         if ("android".equals(packageName)) {
    385                             signature = new Signature("F00D");
    386                         } else {
    387                             signature = new Signature("DEAD");
    388                         }
    389                         info.signatures = new Signature[] {
    390                             signature
    391                         };
    392                         return info;
    393                     }
    394                 });
    395         when(mPackageManager.getApplicationInfoAsUser(anyString(), anyInt(), anyInt()))
    396                 .thenReturn(new ApplicationInfo());
    397         when(mPackageManager.getPackagesForUid(UID_A)).thenReturn(new String[] {PKG_NAME_A});
    398         when(mPackageManager.getPackagesForUid(UID_B)).thenReturn(new String[] {PKG_NAME_B});
    399         when(mPackageManager.getPackagesForUid(UID_C)).thenReturn(new String[] {PKG_NAME_C});
    400         when(mPackageManager.getApplicationInfo(eq(PKG_NAME_A), anyInt()))
    401                 .thenReturn(buildApplicationInfo(PKG_NAME_A));
    402         when(mPackageManager.getApplicationInfo(eq(PKG_NAME_B), anyInt()))
    403                 .thenReturn(buildApplicationInfo(PKG_NAME_B));
    404         when(mPackageManager.getApplicationInfo(eq(PKG_NAME_C), anyInt()))
    405                 .thenReturn(buildApplicationInfo(PKG_NAME_C));
    406         when(mNetworkManager.isBandwidthControlEnabled()).thenReturn(true);
    407         when(mNetworkManager.setDataSaverModeEnabled(anyBoolean())).thenReturn(true);
    408         doNothing().when(mConnectivityManager)
    409                 .registerNetworkCallback(any(), mNetworkCallbackCaptor.capture());
    410 
    411         // Prepare NPMS.
    412         mService.systemReady(mService.networkScoreAndNetworkManagementServiceReady());
    413 
    414         // catch INetworkManagementEventObserver during systemReady()
    415         final ArgumentCaptor<INetworkManagementEventObserver> networkObserver =
    416               ArgumentCaptor.forClass(INetworkManagementEventObserver.class);
    417         verify(mNetworkManager).registerObserver(networkObserver.capture());
    418         mNetworkObserver = networkObserver.getValue();
    419 
    420         NetworkPolicy defaultPolicy = mService.buildDefaultMobilePolicy(0, "");
    421         mDefaultWarningBytes = defaultPolicy.warningBytes;
    422         mDefaultLimitBytes = defaultPolicy.limitBytes;
    423     }
    424 
    425     @After
    426     public void removeFiles() throws Exception {
    427         for (File file : mPolicyDir.listFiles()) {
    428             file.delete();
    429         }
    430     }
    431 
    432     @After
    433     public void unregisterLocalServices() throws Exception {
    434         // Registered by NetworkPolicyManagerService's constructor.
    435         LocalServices.removeServiceForTest(NetworkPolicyManagerInternal.class);
    436 
    437         // Added in registerLocalServices()
    438         LocalServices.removeServiceForTest(ActivityManagerInternal.class);
    439         LocalServices.removeServiceForTest(PowerManagerInternal.class);
    440         LocalServices.removeServiceForTest(DeviceIdleController.LocalService.class);
    441         LocalServices.removeServiceForTest(UsageStatsManagerInternal.class);
    442         LocalServices.removeServiceForTest(NetworkStatsManagerInternal.class);
    443     }
    444 
    445     @After
    446     public void resetClock() throws Exception {
    447         RecurrenceRule.sClock = Clock.systemDefaultZone();
    448     }
    449 
    450     @Test
    451     public void testTurnRestrictBackgroundOn() throws Exception {
    452         assertRestrictBackgroundOff(); // Sanity check.
    453         final FutureIntent futureIntent = newRestrictBackgroundChangedFuture();
    454         setRestrictBackground(true);
    455         assertRestrictBackgroundChangedReceived(futureIntent, null);
    456     }
    457 
    458     @Test
    459     @NetPolicyXml("restrict-background-on.xml")
    460     public void testTurnRestrictBackgroundOff() throws Exception {
    461         assertRestrictBackgroundOn(); // Sanity check.
    462         assertRestrictBackgroundChangedReceived(mFutureIntent, null);
    463         final FutureIntent futureIntent = newRestrictBackgroundChangedFuture();
    464         setRestrictBackground(false);
    465         assertRestrictBackgroundChangedReceived(futureIntent, null);
    466     }
    467 
    468     /**
    469      * Adds whitelist when restrict background is on - app should receive an intent.
    470      */
    471     @Test
    472     @NetPolicyXml("restrict-background-on.xml")
    473     public void testAddRestrictBackgroundWhitelist_restrictBackgroundOn() throws Exception {
    474         assertRestrictBackgroundOn(); // Sanity check.
    475         assertRestrictBackgroundChangedReceived(mFutureIntent, null);
    476         addRestrictBackgroundWhitelist(true);
    477     }
    478 
    479     /**
    480      * Adds whitelist when restrict background is off - app should not receive an intent.
    481      */
    482     @Test
    483     public void testAddRestrictBackgroundWhitelist_restrictBackgroundOff() throws Exception {
    484         assertRestrictBackgroundOff(); // Sanity check.
    485         addRestrictBackgroundWhitelist(false);
    486     }
    487 
    488     private void addRestrictBackgroundWhitelist(boolean expectIntent) throws Exception {
    489         // Sanity checks.
    490         assertWhitelistUids();
    491         assertUidPolicy(UID_A, POLICY_NONE);
    492 
    493         final FutureIntent futureIntent = newRestrictBackgroundChangedFuture();
    494         mPolicyListener.expect().onUidPoliciesChanged(anyInt(), anyInt());
    495 
    496         mService.setUidPolicy(UID_A, POLICY_ALLOW_METERED_BACKGROUND);
    497 
    498         assertWhitelistUids(UID_A);
    499         assertUidPolicy(UID_A, POLICY_ALLOW_METERED_BACKGROUND);
    500         mPolicyListener.waitAndVerify()
    501                 .onUidPoliciesChanged(APP_ID_A, POLICY_ALLOW_METERED_BACKGROUND);
    502         if (expectIntent) {
    503             assertRestrictBackgroundChangedReceived(futureIntent, PKG_NAME_A);
    504         } else {
    505             futureIntent.assertNotReceived();
    506         }
    507     }
    508 
    509     /**
    510      * Removes whitelist when restrict background is on - app should receive an intent.
    511      */
    512     @Test
    513     @NetPolicyXml("uidA-whitelisted-restrict-background-on.xml")
    514     public void testRemoveRestrictBackgroundWhitelist_restrictBackgroundOn() throws Exception {
    515         assertRestrictBackgroundOn(); // Sanity check.
    516         assertRestrictBackgroundChangedReceived(mFutureIntent, null);
    517         removeRestrictBackgroundWhitelist(true);
    518     }
    519 
    520     /**
    521      * Removes whitelist when restrict background is off - app should not receive an intent.
    522      */
    523     @Test
    524     @NetPolicyXml("uidA-whitelisted-restrict-background-off.xml")
    525     public void testRemoveRestrictBackgroundWhitelist_restrictBackgroundOff() throws Exception {
    526         assertRestrictBackgroundOff(); // Sanity check.
    527         removeRestrictBackgroundWhitelist(false);
    528     }
    529 
    530     @Test
    531     public void testLowPowerModeObserver_ListenersRegistered()
    532             throws Exception {
    533         PowerManagerInternal pmInternal = LocalServices.getService(PowerManagerInternal.class);
    534 
    535         verify(pmInternal, atLeast(2)).registerLowPowerModeObserver(any());
    536     }
    537 
    538     @Test
    539     public void updateRestrictBackgroundByLowPowerMode_RestrictOnBeforeBsm_RestrictOnAfterBsm()
    540             throws Exception {
    541         setRestrictBackground(true);
    542         PowerSaveState stateOn = new PowerSaveState.Builder()
    543                 .setGlobalBatterySaverEnabled(true)
    544                 .setBatterySaverEnabled(false)
    545                 .build();
    546         mService.updateRestrictBackgroundByLowPowerModeUL(stateOn);
    547 
    548         // RestrictBackground should be on even though battery saver want to turn it off
    549         assertTrue(mService.getRestrictBackground());
    550 
    551         PowerSaveState stateOff = new PowerSaveState.Builder()
    552                 .setGlobalBatterySaverEnabled(false)
    553                 .setBatterySaverEnabled(false)
    554                 .build();
    555         mService.updateRestrictBackgroundByLowPowerModeUL(stateOff);
    556 
    557         // RestrictBackground should be on, following its previous state
    558         assertTrue(mService.getRestrictBackground());
    559     }
    560 
    561     @Test
    562     public void updateRestrictBackgroundByLowPowerMode_RestrictOffBeforeBsm_RestrictOffAfterBsm()
    563             throws Exception {
    564         setRestrictBackground(false);
    565         PowerSaveState stateOn = new PowerSaveState.Builder()
    566                 .setGlobalBatterySaverEnabled(true)
    567                 .setBatterySaverEnabled(true)
    568                 .build();
    569 
    570         mService.updateRestrictBackgroundByLowPowerModeUL(stateOn);
    571 
    572         // RestrictBackground should be turned on because of battery saver
    573         assertTrue(mService.getRestrictBackground());
    574 
    575         PowerSaveState stateOff = new PowerSaveState.Builder()
    576                 .setGlobalBatterySaverEnabled(false)
    577                 .setBatterySaverEnabled(false)
    578                 .build();
    579         mService.updateRestrictBackgroundByLowPowerModeUL(stateOff);
    580 
    581         // RestrictBackground should be off, following its previous state
    582         assertFalse(mService.getRestrictBackground());
    583     }
    584 
    585     @Test
    586     public void updateRestrictBackgroundByLowPowerMode_StatusChangedInBsm_DoNotRestore()
    587             throws Exception {
    588         setRestrictBackground(true);
    589         PowerSaveState stateOn = new PowerSaveState.Builder()
    590                 .setGlobalBatterySaverEnabled(true)
    591                 .setBatterySaverEnabled(true)
    592                 .build();
    593         mService.updateRestrictBackgroundByLowPowerModeUL(stateOn);
    594 
    595         // RestrictBackground should still be on
    596         assertTrue(mService.getRestrictBackground());
    597 
    598         // User turns off RestrictBackground manually
    599         setRestrictBackground(false);
    600         PowerSaveState stateOff = new PowerSaveState.Builder().setBatterySaverEnabled(
    601                 false).build();
    602         mService.updateRestrictBackgroundByLowPowerModeUL(stateOff);
    603 
    604         // RestrictBackground should be off because user changes it manually
    605         assertFalse(mService.getRestrictBackground());
    606     }
    607 
    608     private void removeRestrictBackgroundWhitelist(boolean expectIntent) throws Exception {
    609         // Sanity checks.
    610         assertWhitelistUids(UID_A);
    611         assertUidPolicy(UID_A, POLICY_ALLOW_METERED_BACKGROUND);
    612 
    613         final FutureIntent futureIntent = newRestrictBackgroundChangedFuture();
    614         mPolicyListener.expect().onUidPoliciesChanged(anyInt(), anyInt());
    615 
    616         mService.setUidPolicy(UID_A, POLICY_NONE);
    617 
    618         assertWhitelistUids();
    619         assertUidPolicy(UID_A, POLICY_NONE);
    620         mPolicyListener.waitAndVerify().onUidPoliciesChanged(APP_ID_A, POLICY_NONE);
    621         if (expectIntent) {
    622             assertRestrictBackgroundChangedReceived(futureIntent, PKG_NAME_A);
    623         } else {
    624             futureIntent.assertNotReceived();
    625         }
    626     }
    627 
    628     /**
    629      * Adds blacklist when restrict background is on - app should not receive an intent.
    630      */
    631     @Test
    632     @NetPolicyXml("restrict-background-on.xml")
    633     public void testAddRestrictBackgroundBlacklist_restrictBackgroundOn() throws Exception {
    634         assertRestrictBackgroundOn(); // Sanity check.
    635         assertRestrictBackgroundChangedReceived(mFutureIntent, null);
    636         addRestrictBackgroundBlacklist(false);
    637     }
    638 
    639     /**
    640      * Adds blacklist when restrict background is off - app should receive an intent.
    641      */
    642     @Test
    643     public void testAddRestrictBackgroundBlacklist_restrictBackgroundOff() throws Exception {
    644         assertRestrictBackgroundOff(); // Sanity check.
    645         addRestrictBackgroundBlacklist(true);
    646     }
    647 
    648     private void addRestrictBackgroundBlacklist(boolean expectIntent) throws Exception {
    649         assertUidPolicy(UID_A, POLICY_NONE); // Sanity check.
    650         final FutureIntent futureIntent = newRestrictBackgroundChangedFuture();
    651         mPolicyListener.expect().onUidPoliciesChanged(anyInt(), anyInt());
    652 
    653         mService.setUidPolicy(UID_A, POLICY_REJECT_METERED_BACKGROUND);
    654 
    655         assertUidPolicy(UID_A, POLICY_REJECT_METERED_BACKGROUND);
    656         mPolicyListener.waitAndVerify()
    657                 .onUidPoliciesChanged(APP_ID_A, POLICY_REJECT_METERED_BACKGROUND);
    658         if (expectIntent) {
    659             assertRestrictBackgroundChangedReceived(futureIntent, PKG_NAME_A);
    660         } else {
    661             futureIntent.assertNotReceived();
    662         }
    663     }
    664 
    665     /**
    666      * Removes blacklist when restrict background is on - app should not receive an intent.
    667      */
    668     @Test
    669     @NetPolicyXml("uidA-blacklisted-restrict-background-on.xml")
    670     public void testRemoveRestrictBackgroundBlacklist_restrictBackgroundOn() throws Exception {
    671         assertRestrictBackgroundOn(); // Sanity check.
    672         assertRestrictBackgroundChangedReceived(mFutureIntent, null);
    673         removeRestrictBackgroundBlacklist(false);
    674     }
    675 
    676     /**
    677      * Removes blacklist when restrict background is off - app should receive an intent.
    678      */
    679     @Test
    680     @NetPolicyXml("uidA-blacklisted-restrict-background-off.xml")
    681     public void testRemoveRestrictBackgroundBlacklist_restrictBackgroundOff() throws Exception {
    682         assertRestrictBackgroundOff(); // Sanity check.
    683         removeRestrictBackgroundBlacklist(true);
    684     }
    685 
    686     private void removeRestrictBackgroundBlacklist(boolean expectIntent) throws Exception {
    687         assertUidPolicy(UID_A, POLICY_REJECT_METERED_BACKGROUND); // Sanity check.
    688         final FutureIntent futureIntent = newRestrictBackgroundChangedFuture();
    689         mPolicyListener.expect().onUidPoliciesChanged(anyInt(), anyInt());
    690 
    691         mService.setUidPolicy(UID_A, POLICY_NONE);
    692 
    693         assertUidPolicy(UID_A, POLICY_NONE);
    694         mPolicyListener.waitAndVerify()
    695                 .onUidPoliciesChanged(APP_ID_A, POLICY_NONE);
    696         if (expectIntent) {
    697             assertRestrictBackgroundChangedReceived(futureIntent, PKG_NAME_A);
    698         } else {
    699             futureIntent.assertNotReceived();
    700         }
    701     }
    702 
    703     @Test
    704     @NetPolicyXml("uidA-blacklisted-restrict-background-on.xml")
    705     public void testBlacklistedAppIsNotNotifiedWhenRestrictBackgroundIsOn() throws Exception {
    706         // Sanity checks.
    707         assertRestrictBackgroundOn();
    708         assertRestrictBackgroundChangedReceived(mFutureIntent, null);
    709         assertUidPolicy(UID_A, POLICY_REJECT_METERED_BACKGROUND);
    710 
    711         final FutureIntent futureIntent = newRestrictBackgroundChangedFuture();
    712         setRestrictBackground(true);
    713         futureIntent.assertNotReceived();
    714     }
    715 
    716     @Test
    717     @NetPolicyXml("uidA-whitelisted-restrict-background-on.xml")
    718     public void testWhitelistedAppIsNotNotifiedWhenRestrictBackgroundIsOn() throws Exception {
    719         // Sanity checks.
    720         assertRestrictBackgroundOn();
    721         assertRestrictBackgroundChangedReceived(mFutureIntent, null);
    722         assertWhitelistUids(UID_A);
    723 
    724         final FutureIntent futureIntent = newRestrictBackgroundChangedFuture();
    725         setRestrictBackground(true);
    726         futureIntent.assertNotReceived();
    727     }
    728 
    729     @Test
    730     @NetPolicyXml("uidA-whitelisted-restrict-background-on.xml")
    731     public void testWhitelistedAppIsNotifiedWhenBlacklisted() throws Exception {
    732         // Sanity checks.
    733         assertRestrictBackgroundOn();
    734         assertRestrictBackgroundChangedReceived(mFutureIntent, null);
    735         assertWhitelistUids(UID_A);
    736 
    737         final FutureIntent futureIntent = newRestrictBackgroundChangedFuture();
    738         mService.setUidPolicy(UID_A, POLICY_REJECT_METERED_BACKGROUND);
    739         assertRestrictBackgroundChangedReceived(futureIntent, PKG_NAME_A);
    740     }
    741 
    742     @Test
    743     @NetPolicyXml("restrict-background-lists-whitelist-format.xml")
    744     public void testRestrictBackgroundLists_whitelistFormat() throws Exception {
    745         restrictBackgroundListsTest();
    746     }
    747 
    748     @Test
    749     @NetPolicyXml("restrict-background-lists-uid-policy-format.xml")
    750     public void testRestrictBackgroundLists_uidPolicyFormat() throws Exception {
    751         restrictBackgroundListsTest();
    752     }
    753 
    754     private void restrictBackgroundListsTest() throws Exception {
    755         // UIds that are whitelisted.
    756         assertWhitelistUids(UID_A, UID_B, UID_C);
    757         assertUidPolicy(UID_A, POLICY_ALLOW_METERED_BACKGROUND);
    758         assertUidPolicy(UID_B, POLICY_ALLOW_METERED_BACKGROUND);
    759         assertUidPolicy(UID_C, POLICY_ALLOW_METERED_BACKGROUND);
    760 
    761         // UIDs that are blacklisted.
    762         assertUidPolicy(UID_D, POLICY_NONE);
    763         assertUidPolicy(UID_E, POLICY_REJECT_METERED_BACKGROUND);
    764 
    765         // UIDS that have legacy policies.
    766         assertUidPolicy(UID_F, 2); // POLICY_ALLOW_BACKGROUND_BATTERY_SAVE
    767 
    768         // Remove whitelist.
    769         mService.setUidPolicy(UID_A, POLICY_NONE);
    770         assertUidPolicy(UID_A, POLICY_NONE);
    771         assertWhitelistUids(UID_B, UID_C);
    772 
    773         // Add whitelist when blacklisted.
    774         mService.setUidPolicy(UID_E, POLICY_ALLOW_METERED_BACKGROUND);
    775         assertUidPolicy(UID_E, POLICY_ALLOW_METERED_BACKGROUND);
    776         assertWhitelistUids(UID_B, UID_C, UID_E);
    777 
    778         // Add blacklist when whitelisted.
    779         mService.setUidPolicy(UID_B, POLICY_REJECT_METERED_BACKGROUND);
    780         assertUidPolicy(UID_B, POLICY_REJECT_METERED_BACKGROUND);
    781         assertWhitelistUids(UID_C, UID_E);
    782     }
    783 
    784     /**
    785      * Tests scenario where an UID had {@code restrict-background} and {@code uid-policy} tags.
    786      */
    787     @Test
    788     @NetPolicyXml("restrict-background-lists-mixed-format.xml")
    789     public void testRestrictBackgroundLists_mixedFormat() throws Exception {
    790         assertWhitelistUids(UID_A, UID_C, UID_D);
    791         assertUidPolicy(UID_A, POLICY_ALLOW_METERED_BACKGROUND);
    792         assertUidPolicy(UID_B, POLICY_REJECT_METERED_BACKGROUND); // Blacklist prevails.
    793         assertUidPolicy(UID_C, (POLICY_ALLOW_METERED_BACKGROUND | 2));
    794         assertUidPolicy(UID_D, POLICY_ALLOW_METERED_BACKGROUND);
    795     }
    796 
    797     @Test
    798     @NetPolicyXml("uids-with-mixed-policies.xml")
    799     public void testGetUidsWithPolicy() throws Exception {
    800         assertContainsInAnyOrder(mService.getUidsWithPolicy(POLICY_NONE));
    801         assertContainsInAnyOrder(mService.getUidsWithPolicy(POLICY_REJECT_METERED_BACKGROUND),
    802                 UID_B, UID_D);
    803         assertContainsInAnyOrder(mService.getUidsWithPolicy(POLICY_ALLOW_METERED_BACKGROUND),
    804                 UID_E, UID_F);
    805         // Legacy (POLICY_ALLOW_BACKGROUND_BATTERY_SAVE)
    806         assertContainsInAnyOrder(mService.getUidsWithPolicy(2),
    807                 UID_C, UID_D, UID_F);
    808     }
    809 
    810     // NOTE: testPolicyChangeTriggersListener() is too superficial, they
    811     // don't check for side-effects (like calls to NetworkManagementService) neither cover all
    812     // different modes (Data Saver, Battery Saver, Doze, App idle, etc...).
    813     // These scenarios are extensively tested on CTS' HostsideRestrictBackgroundNetworkTests.
    814     @Test
    815     public void testUidForeground() throws Exception {
    816         // push all uids into background
    817         callOnUidStateChanged(UID_A, ActivityManager.PROCESS_STATE_SERVICE, 0);
    818         callOnUidStateChanged(UID_B, ActivityManager.PROCESS_STATE_SERVICE, 0);
    819         assertFalse(mService.isUidForeground(UID_A));
    820         assertFalse(mService.isUidForeground(UID_B));
    821 
    822         // push one of the uids into foreground
    823         callOnUidStateChanged(UID_A, ActivityManager.PROCESS_STATE_TOP, 0);
    824         assertTrue(mService.isUidForeground(UID_A));
    825         assertFalse(mService.isUidForeground(UID_B));
    826 
    827         // and swap another uid into foreground
    828         callOnUidStateChanged(UID_A, ActivityManager.PROCESS_STATE_SERVICE, 0);
    829         callOnUidStateChanged(UID_B, ActivityManager.PROCESS_STATE_TOP, 0);
    830         assertFalse(mService.isUidForeground(UID_A));
    831         assertTrue(mService.isUidForeground(UID_B));
    832     }
    833 
    834     private static long computeLastCycleBoundary(long currentTime, NetworkPolicy policy) {
    835         RecurrenceRule.sClock = Clock.fixed(Instant.ofEpochMilli(currentTime),
    836                 ZoneId.systemDefault());
    837         final Iterator<Range<ZonedDateTime>> it = policy.cycleIterator();
    838         while (it.hasNext()) {
    839             final Range<ZonedDateTime> cycle = it.next();
    840             if (cycle.getLower().toInstant().toEpochMilli() < currentTime) {
    841                 return cycle.getLower().toInstant().toEpochMilli();
    842             }
    843         }
    844         throw new IllegalStateException(
    845                 "Failed to find current cycle for " + policy + " at " + currentTime);
    846     }
    847 
    848     private static long computeNextCycleBoundary(long currentTime, NetworkPolicy policy) {
    849         RecurrenceRule.sClock = Clock.fixed(Instant.ofEpochMilli(currentTime),
    850                 ZoneId.systemDefault());
    851         return policy.cycleIterator().next().getUpper().toInstant().toEpochMilli();
    852     }
    853 
    854     @Test
    855     public void testLastCycleBoundaryThisMonth() throws Exception {
    856         // assume cycle day of "5th", which should be in same month
    857         final long currentTime = parseTime("2007-11-14T00:00:00.000Z");
    858         final long expectedCycle = parseTime("2007-11-05T00:00:00.000Z");
    859 
    860         final NetworkPolicy policy = new NetworkPolicy(
    861                 sTemplateWifi, 5, TIMEZONE_UTC, 1024L, 1024L, false);
    862         final long actualCycle = computeLastCycleBoundary(currentTime, policy);
    863         assertTimeEquals(expectedCycle, actualCycle);
    864     }
    865 
    866     @Test
    867     public void testLastCycleBoundaryLastMonth() throws Exception {
    868         // assume cycle day of "20th", which should be in last month
    869         final long currentTime = parseTime("2007-11-14T00:00:00.000Z");
    870         final long expectedCycle = parseTime("2007-10-20T00:00:00.000Z");
    871 
    872         final NetworkPolicy policy = new NetworkPolicy(
    873                 sTemplateWifi, 20, TIMEZONE_UTC, 1024L, 1024L, false);
    874         final long actualCycle = computeLastCycleBoundary(currentTime, policy);
    875         assertTimeEquals(expectedCycle, actualCycle);
    876     }
    877 
    878     @Test
    879     public void testLastCycleBoundaryThisMonthFebruary() throws Exception {
    880         // assume cycle day of "30th" in february; should go to january
    881         final long currentTime = parseTime("2007-02-14T00:00:00.000Z");
    882         final long expectedCycle = parseTime("2007-01-30T00:00:00.000Z");
    883 
    884         final NetworkPolicy policy = new NetworkPolicy(
    885                 sTemplateWifi, 30, TIMEZONE_UTC, 1024L, 1024L, false);
    886         final long actualCycle = computeLastCycleBoundary(currentTime, policy);
    887         assertTimeEquals(expectedCycle, actualCycle);
    888     }
    889 
    890     @Test
    891     public void testLastCycleBoundaryLastMonthFebruary() throws Exception {
    892         // assume cycle day of "30th" in february, which should clamp
    893         final long currentTime = parseTime("2007-03-14T00:00:00.000Z");
    894         final long expectedCycle = parseTime("2007-02-28T23:59:59.999Z");
    895 
    896         final NetworkPolicy policy = new NetworkPolicy(
    897                 sTemplateWifi, 30, TIMEZONE_UTC, 1024L, 1024L, false);
    898         final long actualCycle = computeLastCycleBoundary(currentTime, policy);
    899         assertTimeEquals(expectedCycle, actualCycle);
    900     }
    901 
    902     @Test
    903     public void testCycleBoundaryLeapYear() throws Exception {
    904         final NetworkPolicy policy = new NetworkPolicy(
    905                 sTemplateWifi, 29, TIMEZONE_UTC, 1024L, 1024L, false);
    906 
    907         assertTimeEquals(parseTime("2012-01-29T00:00:00.000Z"),
    908                 computeNextCycleBoundary(parseTime("2012-01-14T00:00:00.000Z"), policy));
    909         assertTimeEquals(parseTime("2012-02-29T00:00:00.000Z"),
    910                 computeNextCycleBoundary(parseTime("2012-02-14T00:00:00.000Z"), policy));
    911         assertTimeEquals(parseTime("2012-02-29T00:00:00.000Z"),
    912                 computeLastCycleBoundary(parseTime("2012-03-14T00:00:00.000Z"), policy));
    913         assertTimeEquals(parseTime("2012-03-29T00:00:00.000Z"),
    914                 computeNextCycleBoundary(parseTime("2012-03-14T00:00:00.000Z"), policy));
    915 
    916         assertTimeEquals(parseTime("2007-01-29T00:00:00.000Z"),
    917                 computeNextCycleBoundary(parseTime("2007-01-14T00:00:00.000Z"), policy));
    918         assertTimeEquals(parseTime("2007-02-28T23:59:59.999Z"),
    919                 computeNextCycleBoundary(parseTime("2007-02-14T00:00:00.000Z"), policy));
    920         assertTimeEquals(parseTime("2007-02-28T23:59:59.999Z"),
    921                 computeLastCycleBoundary(parseTime("2007-03-14T00:00:00.000Z"), policy));
    922         assertTimeEquals(parseTime("2007-03-29T00:00:00.000Z"),
    923                 computeNextCycleBoundary(parseTime("2007-03-14T00:00:00.000Z"), policy));
    924     }
    925 
    926     @Test
    927     public void testNextCycleTimezoneAfterUtc() throws Exception {
    928         // US/Central is UTC-6
    929         final NetworkPolicy policy = new NetworkPolicy(
    930                 sTemplateWifi, 10, "US/Central", 1024L, 1024L, false);
    931         assertTimeEquals(parseTime("2012-01-10T06:00:00.000Z"),
    932                 computeNextCycleBoundary(parseTime("2012-01-05T00:00:00.000Z"), policy));
    933     }
    934 
    935     @Test
    936     public void testNextCycleTimezoneBeforeUtc() throws Exception {
    937         // Israel is UTC+2
    938         final NetworkPolicy policy = new NetworkPolicy(
    939                 sTemplateWifi, 10, "Israel", 1024L, 1024L, false);
    940         assertTimeEquals(parseTime("2012-01-09T22:00:00.000Z"),
    941                 computeNextCycleBoundary(parseTime("2012-01-05T00:00:00.000Z"), policy));
    942     }
    943 
    944     @Test
    945     public void testCycleTodayJanuary() throws Exception {
    946         final NetworkPolicy policy = new NetworkPolicy(
    947                 sTemplateWifi, 14, "US/Pacific", 1024L, 1024L, false);
    948 
    949         assertTimeEquals(parseTime("2013-01-14T00:00:00.000-08:00"),
    950                 computeNextCycleBoundary(parseTime("2013-01-13T23:59:59.000-08:00"), policy));
    951         assertTimeEquals(parseTime("2013-02-14T00:00:00.000-08:00"),
    952                 computeNextCycleBoundary(parseTime("2013-01-14T00:00:01.000-08:00"), policy));
    953         assertTimeEquals(parseTime("2013-02-14T00:00:00.000-08:00"),
    954                 computeNextCycleBoundary(parseTime("2013-01-14T15:11:00.000-08:00"), policy));
    955 
    956         assertTimeEquals(parseTime("2012-12-14T00:00:00.000-08:00"),
    957                 computeLastCycleBoundary(parseTime("2013-01-13T23:59:59.000-08:00"), policy));
    958         assertTimeEquals(parseTime("2013-01-14T00:00:00.000-08:00"),
    959                 computeLastCycleBoundary(parseTime("2013-01-14T00:00:01.000-08:00"), policy));
    960         assertTimeEquals(parseTime("2013-01-14T00:00:00.000-08:00"),
    961                 computeLastCycleBoundary(parseTime("2013-01-14T15:11:00.000-08:00"), policy));
    962     }
    963 
    964     @Test
    965     public void testNetworkPolicyAppliedCycleLastMonth() throws Exception {
    966         NetworkState[] state = null;
    967         NetworkStats stats = null;
    968 
    969         final int CYCLE_DAY = 15;
    970         final long NOW = parseTime("2007-03-10T00:00Z");
    971         final long CYCLE_START = parseTime("2007-02-15T00:00Z");
    972         final long CYCLE_END = parseTime("2007-03-15T00:00Z");
    973 
    974         setCurrentTimeMillis(NOW);
    975 
    976         // first, pretend that wifi network comes online. no policy active,
    977         // which means we shouldn't push limit to interface.
    978         state = new NetworkState[] { buildWifi() };
    979         when(mConnManager.getAllNetworkState()).thenReturn(state);
    980 
    981         mPolicyListener.expect().onMeteredIfacesChanged(any());
    982         mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION));
    983         mPolicyListener.waitAndVerify().onMeteredIfacesChanged(any());
    984 
    985         // now change cycle to be on 15th, and test in early march, to verify we
    986         // pick cycle day in previous month.
    987         when(mConnManager.getAllNetworkState()).thenReturn(state);
    988 
    989         // pretend that 512 bytes total have happened
    990         stats = new NetworkStats(getElapsedRealtime(), 1)
    991                 .addIfaceValues(TEST_IFACE, 256L, 2L, 256L, 2L);
    992         when(mStatsService.getNetworkTotalBytes(sTemplateWifi, CYCLE_START, CYCLE_END))
    993                 .thenReturn(stats.getTotalBytes());
    994 
    995         mPolicyListener.expect().onMeteredIfacesChanged(any());
    996         setNetworkPolicies(new NetworkPolicy(
    997                 sTemplateWifi, CYCLE_DAY, TIMEZONE_UTC, 1 * MB_IN_BYTES, 2 * MB_IN_BYTES, false));
    998         mPolicyListener.waitAndVerify().onMeteredIfacesChanged(eq(new String[]{TEST_IFACE}));
    999 
   1000         verify(mNetworkManager, atLeastOnce()).setInterfaceQuota(TEST_IFACE,
   1001                 (2 * MB_IN_BYTES) - 512);
   1002     }
   1003 
   1004     @Test
   1005     public void testNotificationWarningLimitSnooze() throws Exception {
   1006         // Create a place to store fake usage
   1007         final NetworkStatsHistory history = new NetworkStatsHistory(TimeUnit.HOURS.toMillis(1));
   1008         final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 0);
   1009         when(mStatsService.getNetworkTotalBytes(any(), anyLong(), anyLong()))
   1010                 .thenAnswer(new Answer<Long>() {
   1011                     @Override
   1012                     public Long answer(InvocationOnMock invocation) throws Throwable {
   1013                         final NetworkStatsHistory.Entry entry = history.getValues(
   1014                                 invocation.getArgument(1), invocation.getArgument(2), null);
   1015                         return entry.rxBytes + entry.txBytes;
   1016                     }
   1017                 });
   1018         when(mStatsService.getNetworkUidBytes(any(), anyLong(), anyLong()))
   1019                 .thenAnswer(new Answer<NetworkStats>() {
   1020                     @Override
   1021                     public NetworkStats answer(InvocationOnMock invocation) throws Throwable {
   1022                         return stats;
   1023                     }
   1024                 });
   1025 
   1026         // Get active mobile network in place
   1027         expectMobileDefaults();
   1028         mService.updateNetworks();
   1029 
   1030         // Define simple data plan
   1031         final SubscriptionPlan plan = buildMonthlyDataPlan(
   1032                 ZonedDateTime.parse("2015-11-01T00:00:00.00Z"), DataUnit.MEGABYTES.toBytes(1800));
   1033         mService.setSubscriptionPlans(TEST_SUB_ID, new SubscriptionPlan[] { plan },
   1034                 mServiceContext.getOpPackageName());
   1035 
   1036         // We're 20% through the month (6 days)
   1037         final long start = parseTime("2015-11-01T00:00Z");
   1038         final long end = parseTime("2015-11-07T00:00Z");
   1039         setCurrentTimeMillis(end);
   1040 
   1041         // Normal usage means no notification
   1042         {
   1043             history.clear();
   1044             history.recordData(start, end,
   1045                     new NetworkStats.Entry(DataUnit.MEGABYTES.toBytes(360), 0L, 0L, 0L, 0));
   1046 
   1047             reset(mTelephonyManager, mNetworkManager, mNotifManager);
   1048             expectMobileDefaults();
   1049 
   1050             mService.updateNetworks();
   1051 
   1052             verify(mTelephonyManager, atLeastOnce()).setPolicyDataEnabled(true, TEST_SUB_ID);
   1053             verify(mNetworkManager, atLeastOnce()).setInterfaceQuota(TEST_IFACE,
   1054                     DataUnit.MEGABYTES.toBytes(1800 - 360));
   1055             verify(mNotifManager, never()).notifyAsUser(any(), anyInt(), any(), any());
   1056         }
   1057 
   1058         // Push over warning
   1059         {
   1060             history.clear();
   1061             history.recordData(start, end,
   1062                     new NetworkStats.Entry(DataUnit.MEGABYTES.toBytes(1799), 0L, 0L, 0L, 0));
   1063 
   1064             reset(mTelephonyManager, mNetworkManager, mNotifManager);
   1065             expectMobileDefaults();
   1066 
   1067             mService.updateNetworks();
   1068 
   1069             verify(mTelephonyManager, atLeastOnce()).setPolicyDataEnabled(true, TEST_SUB_ID);
   1070             verify(mNetworkManager, atLeastOnce()).setInterfaceQuota(TEST_IFACE,
   1071                     DataUnit.MEGABYTES.toBytes(1800 - 1799));
   1072             verify(mNotifManager, atLeastOnce()).notifyAsUser(any(), eq(TYPE_WARNING),
   1073                     isA(Notification.class), eq(UserHandle.ALL));
   1074         }
   1075 
   1076         // Push over limit
   1077         {
   1078             history.clear();
   1079             history.recordData(start, end,
   1080                     new NetworkStats.Entry(DataUnit.MEGABYTES.toBytes(1810), 0L, 0L, 0L, 0));
   1081 
   1082             reset(mTelephonyManager, mNetworkManager, mNotifManager);
   1083             expectMobileDefaults();
   1084 
   1085             mService.updateNetworks();
   1086 
   1087             verify(mTelephonyManager, atLeastOnce()).setPolicyDataEnabled(false, TEST_SUB_ID);
   1088             verify(mNetworkManager, atLeastOnce()).setInterfaceQuota(TEST_IFACE, 1);
   1089             verify(mNotifManager, atLeastOnce()).notifyAsUser(any(), eq(TYPE_LIMIT),
   1090                     isA(Notification.class), eq(UserHandle.ALL));
   1091         }
   1092 
   1093         // Snooze limit
   1094         {
   1095             reset(mTelephonyManager, mNetworkManager, mNotifManager);
   1096             expectMobileDefaults();
   1097 
   1098             mService.snoozeLimit(NetworkTemplate.buildTemplateMobileAll(TEST_IMSI));
   1099             mService.updateNetworks();
   1100 
   1101             verify(mTelephonyManager, atLeastOnce()).setPolicyDataEnabled(true, TEST_SUB_ID);
   1102             verify(mNetworkManager, atLeastOnce()).setInterfaceQuota(TEST_IFACE,
   1103                     Long.MAX_VALUE);
   1104             verify(mNotifManager, atLeastOnce()).notifyAsUser(any(), eq(TYPE_LIMIT_SNOOZED),
   1105                     isA(Notification.class), eq(UserHandle.ALL));
   1106         }
   1107     }
   1108 
   1109     @Test
   1110     public void testNotificationRapid() throws Exception {
   1111         // Create a place to store fake usage
   1112         final NetworkStatsHistory history = new NetworkStatsHistory(TimeUnit.HOURS.toMillis(1));
   1113         final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 0);
   1114         when(mStatsService.getNetworkTotalBytes(any(), anyLong(), anyLong()))
   1115                 .thenAnswer(new Answer<Long>() {
   1116                     @Override
   1117                     public Long answer(InvocationOnMock invocation) throws Throwable {
   1118                         final NetworkStatsHistory.Entry entry = history.getValues(
   1119                                 invocation.getArgument(1), invocation.getArgument(2), null);
   1120                         return entry.rxBytes + entry.txBytes;
   1121                     }
   1122                 });
   1123         when(mStatsService.getNetworkUidBytes(any(), anyLong(), anyLong()))
   1124                 .thenAnswer(new Answer<NetworkStats>() {
   1125                     @Override
   1126                     public NetworkStats answer(InvocationOnMock invocation) throws Throwable {
   1127                         return stats;
   1128                     }
   1129                 });
   1130 
   1131         // Get active mobile network in place
   1132         expectMobileDefaults();
   1133         mService.updateNetworks();
   1134 
   1135         // Define simple data plan which gives us effectively 60MB/day
   1136         final SubscriptionPlan plan = buildMonthlyDataPlan(
   1137                 ZonedDateTime.parse("2015-11-01T00:00:00.00Z"), DataUnit.MEGABYTES.toBytes(1800));
   1138         mService.setSubscriptionPlans(TEST_SUB_ID, new SubscriptionPlan[] { plan },
   1139                 mServiceContext.getOpPackageName());
   1140 
   1141         // We're 20% through the month (6 days)
   1142         final long start = parseTime("2015-11-01T00:00Z");
   1143         final long end = parseTime("2015-11-07T00:00Z");
   1144         setCurrentTimeMillis(end);
   1145 
   1146         // Using 20% data in 20% time is normal
   1147         {
   1148             history.clear();
   1149             history.recordData(start, end,
   1150                     new NetworkStats.Entry(DataUnit.MEGABYTES.toBytes(360), 0L, 0L, 0L, 0));
   1151 
   1152             reset(mNotifManager);
   1153             mService.updateNetworks();
   1154             verify(mNotifManager, never()).notifyAsUser(any(), anyInt(), any(), any());
   1155         }
   1156 
   1157         // Using 80% data in 20% time is alarming; but spread equally among
   1158         // three UIDs means we get generic alert
   1159         {
   1160             history.clear();
   1161             history.recordData(start, end,
   1162                     new NetworkStats.Entry(DataUnit.MEGABYTES.toBytes(1440), 0L, 0L, 0L, 0));
   1163             stats.clear();
   1164             stats.addValues(IFACE_ALL, UID_A, SET_ALL, TAG_ALL,
   1165                     DataUnit.MEGABYTES.toBytes(480), 0, 0, 0, 0);
   1166             stats.addValues(IFACE_ALL, UID_B, SET_ALL, TAG_ALL,
   1167                     DataUnit.MEGABYTES.toBytes(480), 0, 0, 0, 0);
   1168             stats.addValues(IFACE_ALL, UID_C, SET_ALL, TAG_ALL,
   1169                     DataUnit.MEGABYTES.toBytes(480), 0, 0, 0, 0);
   1170 
   1171             reset(mNotifManager);
   1172             mService.updateNetworks();
   1173 
   1174             final ArgumentCaptor<Notification> notif = ArgumentCaptor.forClass(Notification.class);
   1175             verify(mNotifManager, atLeastOnce()).notifyAsUser(any(), eq(TYPE_RAPID),
   1176                     notif.capture(), eq(UserHandle.ALL));
   1177 
   1178             final String text = notif.getValue().extras.getCharSequence(Notification.EXTRA_TEXT)
   1179                     .toString();
   1180             assertFalse(text.contains(PKG_NAME_A));
   1181             assertFalse(text.contains(PKG_NAME_B));
   1182             assertFalse(text.contains(PKG_NAME_C));
   1183         }
   1184 
   1185         // Using 80% data in 20% time is alarming; but mostly done by one UID
   1186         // means we get specific alert
   1187         {
   1188             history.clear();
   1189             history.recordData(start, end,
   1190                     new NetworkStats.Entry(DataUnit.MEGABYTES.toBytes(1440), 0L, 0L, 0L, 0));
   1191             stats.clear();
   1192             stats.addValues(IFACE_ALL, UID_A, SET_ALL, TAG_ALL,
   1193                     DataUnit.MEGABYTES.toBytes(960), 0, 0, 0, 0);
   1194             stats.addValues(IFACE_ALL, UID_B, SET_ALL, TAG_ALL,
   1195                     DataUnit.MEGABYTES.toBytes(480), 0, 0, 0, 0);
   1196 
   1197             reset(mNotifManager);
   1198             mService.updateNetworks();
   1199 
   1200             final ArgumentCaptor<Notification> notif = ArgumentCaptor.forClass(Notification.class);
   1201             verify(mNotifManager, atLeastOnce()).notifyAsUser(any(), eq(TYPE_RAPID),
   1202                     notif.capture(), eq(UserHandle.ALL));
   1203 
   1204             final String text = notif.getValue().extras.getCharSequence(Notification.EXTRA_TEXT)
   1205                     .toString();
   1206             assertTrue(text.contains(PKG_NAME_A));
   1207             assertFalse(text.contains(PKG_NAME_B));
   1208             assertFalse(text.contains(PKG_NAME_C));
   1209         }
   1210     }
   1211 
   1212     @Test
   1213     public void testMeteredNetworkWithoutLimit() throws Exception {
   1214         NetworkState[] state = null;
   1215         NetworkStats stats = null;
   1216 
   1217         final long TIME_FEB_15 = 1171497600000L;
   1218         final long TIME_MAR_10 = 1173484800000L;
   1219         final int CYCLE_DAY = 15;
   1220 
   1221         setCurrentTimeMillis(TIME_MAR_10);
   1222 
   1223         // bring up wifi network with metered policy
   1224         state = new NetworkState[] { buildWifi() };
   1225         stats = new NetworkStats(getElapsedRealtime(), 1)
   1226                 .addIfaceValues(TEST_IFACE, 0L, 0L, 0L, 0L);
   1227 
   1228         {
   1229             when(mConnManager.getAllNetworkState()).thenReturn(state);
   1230             when(mStatsService.getNetworkTotalBytes(sTemplateWifi, TIME_FEB_15,
   1231                     currentTimeMillis())).thenReturn(stats.getTotalBytes());
   1232 
   1233             mPolicyListener.expect().onMeteredIfacesChanged(any());
   1234             setNetworkPolicies(new NetworkPolicy(
   1235                     sTemplateWifi, CYCLE_DAY, TIMEZONE_UTC, WARNING_DISABLED, LIMIT_DISABLED,
   1236                     true));
   1237             mPolicyListener.waitAndVerify().onMeteredIfacesChanged(eq(new String[]{TEST_IFACE}));
   1238 
   1239             verify(mNetworkManager, atLeastOnce()).setInterfaceQuota(TEST_IFACE,
   1240                     Long.MAX_VALUE);
   1241         }
   1242     }
   1243 
   1244     @Test
   1245     public void testOnUidStateChanged_notifyAMS() throws Exception {
   1246         final long procStateSeq = 222;
   1247         callOnUidStateChanged(UID_A, ActivityManager.PROCESS_STATE_SERVICE, procStateSeq);
   1248         verify(mActivityManagerInternal).notifyNetworkPolicyRulesUpdated(UID_A, procStateSeq);
   1249     }
   1250 
   1251     private void callOnUidStateChanged(int uid, int procState, long procStateSeq)
   1252             throws Exception {
   1253         mUidObserver.onUidStateChanged(uid, procState, procStateSeq);
   1254         final CountDownLatch latch = new CountDownLatch(1);
   1255         mService.mUidEventHandler.post(() -> {
   1256             latch.countDown();
   1257         });
   1258         latch.await(2, TimeUnit.SECONDS);
   1259     }
   1260 
   1261     private void assertCycleDayAsExpected(PersistableBundle config, int carrierCycleDay,
   1262             boolean expectValid) {
   1263         config.putInt(KEY_MONTHLY_DATA_CYCLE_DAY_INT, carrierCycleDay);
   1264         int actualCycleDay = mService.getCycleDayFromCarrierConfig(config,
   1265                 INVALID_CARRIER_CONFIG_VALUE);
   1266         if (expectValid) {
   1267             assertEquals(carrierCycleDay, actualCycleDay);
   1268         } else {
   1269             // INVALID_CARRIER_CONFIG_VALUE is returned for invalid values
   1270             assertEquals(INVALID_CARRIER_CONFIG_VALUE, actualCycleDay);
   1271         }
   1272     }
   1273 
   1274     @Test
   1275     public void testGetCycleDayFromCarrierConfig() {
   1276         PersistableBundle config = CarrierConfigManager.getDefaultConfig();
   1277         final Calendar cal = Calendar.getInstance();
   1278         int actualCycleDay;
   1279 
   1280         config.putInt(KEY_MONTHLY_DATA_CYCLE_DAY_INT, DATA_CYCLE_USE_PLATFORM_DEFAULT);
   1281         actualCycleDay = mService.getCycleDayFromCarrierConfig(config, DEFAULT_CYCLE_DAY);
   1282         assertEquals(DEFAULT_CYCLE_DAY, actualCycleDay);
   1283 
   1284         // null config returns a default value
   1285         actualCycleDay = mService.getCycleDayFromCarrierConfig(null, DEFAULT_CYCLE_DAY);
   1286         assertEquals(DEFAULT_CYCLE_DAY, actualCycleDay);
   1287 
   1288         // Sane, non-default values
   1289         assertCycleDayAsExpected(config, 1, true);
   1290         assertCycleDayAsExpected(config, cal.getMaximum(Calendar.DAY_OF_MONTH), true);
   1291         assertCycleDayAsExpected(config, cal.getMinimum(Calendar.DAY_OF_MONTH), true);
   1292 
   1293         // Invalid values
   1294         assertCycleDayAsExpected(config, 0, false);
   1295         assertCycleDayAsExpected(config, DATA_CYCLE_THRESHOLD_DISABLED, false);
   1296         assertCycleDayAsExpected(config, cal.getMaximum(Calendar.DAY_OF_MONTH) + 1, false);
   1297         assertCycleDayAsExpected(config, cal.getMinimum(Calendar.DAY_OF_MONTH) - 5, false);
   1298     }
   1299 
   1300     private void assertWarningBytesAsExpected(PersistableBundle config, long carrierWarningBytes,
   1301             long expected) {
   1302         config.putLong(KEY_DATA_WARNING_THRESHOLD_BYTES_LONG, carrierWarningBytes);
   1303         long actualWarning = mService.getWarningBytesFromCarrierConfig(config,
   1304                 INVALID_CARRIER_CONFIG_VALUE);
   1305         assertEquals(expected, actualWarning);
   1306     }
   1307 
   1308     @Test
   1309     public void testGetWarningBytesFromCarrierConfig() {
   1310         PersistableBundle config = CarrierConfigManager.getDefaultConfig();
   1311         long actualWarningBytes;
   1312 
   1313         assertWarningBytesAsExpected(config, DATA_CYCLE_USE_PLATFORM_DEFAULT,
   1314                 mDefaultWarningBytes);
   1315         assertWarningBytesAsExpected(config, DATA_CYCLE_THRESHOLD_DISABLED, WARNING_DISABLED);
   1316         assertWarningBytesAsExpected(config, 0, 0);
   1317         // not a valid value
   1318         assertWarningBytesAsExpected(config, -1000, INVALID_CARRIER_CONFIG_VALUE);
   1319 
   1320         // null config returns a default value
   1321         actualWarningBytes = mService.getWarningBytesFromCarrierConfig(null, mDefaultWarningBytes);
   1322         assertEquals(mDefaultWarningBytes, actualWarningBytes);
   1323     }
   1324 
   1325     private void assertLimitBytesAsExpected(PersistableBundle config,  long carrierWarningBytes,
   1326             long expected) {
   1327         config.putLong(KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG, carrierWarningBytes);
   1328         long actualWarning = mService.getLimitBytesFromCarrierConfig(config,
   1329                 INVALID_CARRIER_CONFIG_VALUE);
   1330         assertEquals(expected, actualWarning);
   1331     }
   1332 
   1333     @Test
   1334     public void testGetLimitBytesFromCarrierConfig() {
   1335         PersistableBundle config = CarrierConfigManager.getDefaultConfig();
   1336         long actualLimitBytes;
   1337 
   1338         assertLimitBytesAsExpected(config, DATA_CYCLE_USE_PLATFORM_DEFAULT,
   1339                 mDefaultLimitBytes);
   1340         assertLimitBytesAsExpected(config, DATA_CYCLE_THRESHOLD_DISABLED, LIMIT_DISABLED);
   1341         assertLimitBytesAsExpected(config, 0, 0);
   1342         // not a valid value
   1343         assertLimitBytesAsExpected(config, -1000, INVALID_CARRIER_CONFIG_VALUE);
   1344 
   1345         // null config returns a default value
   1346         actualLimitBytes = mService.getWarningBytesFromCarrierConfig(null, mDefaultLimitBytes);
   1347         assertEquals(mDefaultLimitBytes, actualLimitBytes);
   1348     }
   1349 
   1350     private PersistableBundle setupUpdateMobilePolicyCycleTests() throws RemoteException {
   1351         when(mConnManager.getAllNetworkState()).thenReturn(new NetworkState[0]);
   1352         when(mSubscriptionManager.getActiveSubscriptionIdList()).thenReturn(new int[]{FAKE_SUB_ID});
   1353         when(mTelephonyManager.getSubscriberId(FAKE_SUB_ID)).thenReturn(FAKE_SUBSCRIBER_ID);
   1354         PersistableBundle bundle = CarrierConfigManager.getDefaultConfig();
   1355         when(mCarrierConfigManager.getConfigForSubId(FAKE_SUB_ID)).thenReturn(bundle);
   1356         setNetworkPolicies(buildDefaultFakeMobilePolicy());
   1357         return bundle;
   1358     }
   1359 
   1360     @Test
   1361     public void testUpdateMobilePolicyCycleWithNullConfig() throws RemoteException {
   1362         when(mConnManager.getAllNetworkState()).thenReturn(new NetworkState[0]);
   1363         when(mSubscriptionManager.getActiveSubscriptionIdList()).thenReturn(new int[]{FAKE_SUB_ID});
   1364         when(mTelephonyManager.getSubscriberId(FAKE_SUB_ID)).thenReturn(FAKE_SUBSCRIBER_ID);
   1365         when(mCarrierConfigManager.getConfigForSubId(FAKE_SUB_ID)).thenReturn(null);
   1366         setNetworkPolicies(buildDefaultFakeMobilePolicy());
   1367         // smoke test to make sure no errors are raised
   1368         mServiceContext.sendBroadcast(
   1369                 new Intent(ACTION_CARRIER_CONFIG_CHANGED)
   1370                         .putExtra(PhoneConstants.SUBSCRIPTION_KEY, FAKE_SUB_ID)
   1371         );
   1372         assertNetworkPolicyEquals(DEFAULT_CYCLE_DAY, mDefaultWarningBytes, mDefaultLimitBytes,
   1373                 true);
   1374     }
   1375 
   1376     @Test
   1377     public void testUpdateMobilePolicyCycleWithInvalidConfig() throws RemoteException {
   1378         PersistableBundle bundle = setupUpdateMobilePolicyCycleTests();
   1379         // Test with an invalid CarrierConfig, there should be no changes or crashes.
   1380         bundle.putInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT, -100);
   1381         bundle.putLong(CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG, -100);
   1382         bundle.putLong(CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG, -100);
   1383         mServiceContext.sendBroadcast(
   1384                 new Intent(ACTION_CARRIER_CONFIG_CHANGED)
   1385                         .putExtra(PhoneConstants.SUBSCRIPTION_KEY, FAKE_SUB_ID)
   1386         );
   1387 
   1388         assertNetworkPolicyEquals(DEFAULT_CYCLE_DAY, mDefaultWarningBytes, mDefaultLimitBytes,
   1389                 true);
   1390     }
   1391 
   1392     @Test
   1393     public void testUpdateMobilePolicyCycleWithDefaultConfig() throws RemoteException {
   1394         PersistableBundle bundle = setupUpdateMobilePolicyCycleTests();
   1395         // Test that we respect the platform values when told to
   1396         bundle.putInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT,
   1397                 DATA_CYCLE_USE_PLATFORM_DEFAULT);
   1398         bundle.putLong(CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG,
   1399                 DATA_CYCLE_USE_PLATFORM_DEFAULT);
   1400         bundle.putLong(CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG,
   1401                 DATA_CYCLE_USE_PLATFORM_DEFAULT);
   1402         mServiceContext.sendBroadcast(
   1403                 new Intent(ACTION_CARRIER_CONFIG_CHANGED)
   1404                         .putExtra(PhoneConstants.SUBSCRIPTION_KEY, FAKE_SUB_ID)
   1405         );
   1406 
   1407         assertNetworkPolicyEquals(DEFAULT_CYCLE_DAY, mDefaultWarningBytes, mDefaultLimitBytes,
   1408                 true);
   1409     }
   1410 
   1411     @Test
   1412     public void testUpdateMobilePolicyCycleWithUserOverrides() throws RemoteException {
   1413         PersistableBundle bundle = setupUpdateMobilePolicyCycleTests();
   1414 
   1415         // inferred = false implies that a user manually modified this policy.
   1416         NetworkPolicy policy = buildDefaultFakeMobilePolicy();
   1417         policy.inferred = false;
   1418         setNetworkPolicies(policy);
   1419 
   1420         bundle.putInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT, 31);
   1421         bundle.putLong(CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG, 9999);
   1422         bundle.putLong(CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG,
   1423                 DATA_CYCLE_THRESHOLD_DISABLED);
   1424         mServiceContext.sendBroadcast(
   1425                 new Intent(ACTION_CARRIER_CONFIG_CHANGED)
   1426                         .putExtra(PhoneConstants.SUBSCRIPTION_KEY, FAKE_SUB_ID)
   1427         );
   1428 
   1429         // The policy still shouldn't change, because we don't want to overwrite user settings.
   1430         assertNetworkPolicyEquals(DEFAULT_CYCLE_DAY, mDefaultWarningBytes, mDefaultLimitBytes,
   1431                 false);
   1432     }
   1433 
   1434     @Test
   1435     public void testUpdateMobilePolicyCycleUpdatesDataCycle() throws RemoteException {
   1436         PersistableBundle bundle = setupUpdateMobilePolicyCycleTests();
   1437 
   1438         bundle.putInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT, 31);
   1439         bundle.putLong(CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG, 9999);
   1440         bundle.putLong(CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG, 9999);
   1441         mServiceContext.sendBroadcast(
   1442                 new Intent(ACTION_CARRIER_CONFIG_CHANGED)
   1443                         .putExtra(PhoneConstants.SUBSCRIPTION_KEY, FAKE_SUB_ID)
   1444         );
   1445 
   1446         assertNetworkPolicyEquals(31, 9999, 9999, true);
   1447     }
   1448 
   1449     @Test
   1450     public void testUpdateMobilePolicyCycleDisableThresholds() throws RemoteException {
   1451         PersistableBundle bundle = setupUpdateMobilePolicyCycleTests();
   1452 
   1453         bundle.putInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT, 31);
   1454         bundle.putLong(CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG,
   1455                 DATA_CYCLE_THRESHOLD_DISABLED);
   1456         bundle.putLong(CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG,
   1457                 DATA_CYCLE_THRESHOLD_DISABLED);
   1458         mServiceContext.sendBroadcast(
   1459                 new Intent(ACTION_CARRIER_CONFIG_CHANGED)
   1460                         .putExtra(PhoneConstants.SUBSCRIPTION_KEY, FAKE_SUB_ID)
   1461         );
   1462 
   1463         assertNetworkPolicyEquals(31, WARNING_DISABLED, LIMIT_DISABLED, true);
   1464     }
   1465 
   1466     @Test
   1467     public void testUpdateMobilePolicyCycleRevertsToDefault() throws RemoteException {
   1468         PersistableBundle bundle = setupUpdateMobilePolicyCycleTests();
   1469 
   1470         bundle.putInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT, 31);
   1471         bundle.putLong(CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG,
   1472                 DATA_CYCLE_THRESHOLD_DISABLED);
   1473         bundle.putLong(CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG,
   1474                 DATA_CYCLE_THRESHOLD_DISABLED);
   1475         mServiceContext.sendBroadcast(
   1476                 new Intent(ACTION_CARRIER_CONFIG_CHANGED)
   1477                         .putExtra(PhoneConstants.SUBSCRIPTION_KEY, FAKE_SUB_ID)
   1478         );
   1479         assertNetworkPolicyEquals(31, WARNING_DISABLED, LIMIT_DISABLED, true);
   1480 
   1481         // If the user switches carriers to one that doesn't use a CarrierConfig, we should revert
   1482         // to the default data limit and warning. The cycle date doesn't need to revert as it's
   1483         // arbitrary anyways.
   1484         bundle.putInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT,
   1485                 DATA_CYCLE_USE_PLATFORM_DEFAULT);
   1486         bundle.putLong(CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG,
   1487                 DATA_CYCLE_USE_PLATFORM_DEFAULT);
   1488         bundle.putLong(CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG,
   1489                 DATA_CYCLE_USE_PLATFORM_DEFAULT);
   1490         mServiceContext.sendBroadcast(
   1491                 new Intent(ACTION_CARRIER_CONFIG_CHANGED)
   1492                         .putExtra(PhoneConstants.SUBSCRIPTION_KEY, FAKE_SUB_ID)
   1493         );
   1494 
   1495         assertNetworkPolicyEquals(31, mDefaultWarningBytes, mDefaultLimitBytes,
   1496                 true);
   1497     }
   1498 
   1499     @Test
   1500     public void testOpportunisticQuota() throws Exception {
   1501         final Network net = new Network(TEST_NET_ID);
   1502         final NetworkPolicyManagerInternal internal = LocalServices
   1503                 .getService(NetworkPolicyManagerInternal.class);
   1504 
   1505         // Create a place to store fake usage
   1506         final NetworkStatsHistory history = new NetworkStatsHistory(TimeUnit.HOURS.toMillis(1));
   1507         final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 0);
   1508         when(mStatsService.getNetworkTotalBytes(any(), anyLong(), anyLong()))
   1509                 .thenAnswer(invocation -> {
   1510                     final NetworkStatsHistory.Entry entry = history.getValues(
   1511                             invocation.getArgument(1), invocation.getArgument(2), null);
   1512                     return entry.rxBytes + entry.txBytes;
   1513                 });
   1514         when(mStatsService.getNetworkUidBytes(any(), anyLong(), anyLong()))
   1515                 .thenReturn(stats);
   1516 
   1517         // Get active mobile network in place
   1518         expectMobileDefaults();
   1519         mService.updateNetworks();
   1520 
   1521         // We're 20% through the month (6 days)
   1522         final long start = parseTime("2015-11-01T00:00Z");
   1523         final long end = parseTime("2015-11-07T00:00Z");
   1524         setCurrentTimeMillis(end);
   1525 
   1526         // Get some data usage in place
   1527         history.clear();
   1528         history.recordData(start, end,
   1529                 new NetworkStats.Entry(DataUnit.MEGABYTES.toBytes(360), 0L, 0L, 0L, 0));
   1530 
   1531         // No data plan
   1532         {
   1533             reset(mTelephonyManager, mNetworkManager, mNotifManager);
   1534             expectMobileDefaults();
   1535 
   1536             mService.updateNetworks();
   1537 
   1538             // No quotas
   1539             assertEquals(OPPORTUNISTIC_QUOTA_UNKNOWN,
   1540                     internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_JOBS));
   1541             assertEquals(OPPORTUNISTIC_QUOTA_UNKNOWN,
   1542                     internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_MULTIPATH));
   1543         }
   1544 
   1545         // Limited data plan
   1546         {
   1547             final SubscriptionPlan plan = buildMonthlyDataPlan(
   1548                     ZonedDateTime.parse("2015-11-01T00:00:00.00Z"),
   1549                     DataUnit.MEGABYTES.toBytes(1800));
   1550             mService.setSubscriptionPlans(TEST_SUB_ID, new SubscriptionPlan[]{plan},
   1551                     mServiceContext.getOpPackageName());
   1552 
   1553             reset(mTelephonyManager, mNetworkManager, mNotifManager);
   1554             expectMobileDefaults();
   1555 
   1556             mService.updateNetworks();
   1557 
   1558             // We have 1440MB and 24 days left, which is 60MB/day; assuming 10%
   1559             // for quota split equally between two types gives 3MB.
   1560             assertEquals(DataUnit.MEGABYTES.toBytes(3),
   1561                     internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_JOBS));
   1562             assertEquals(DataUnit.MEGABYTES.toBytes(3),
   1563                     internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_MULTIPATH));
   1564         }
   1565 
   1566         // Limited data plan, over quota
   1567         {
   1568             final SubscriptionPlan plan = buildMonthlyDataPlan(
   1569                     ZonedDateTime.parse("2015-11-01T00:00:00.00Z"),
   1570                     DataUnit.MEGABYTES.toBytes(100));
   1571             mService.setSubscriptionPlans(TEST_SUB_ID, new SubscriptionPlan[]{plan},
   1572                     mServiceContext.getOpPackageName());
   1573 
   1574             reset(mTelephonyManager, mNetworkManager, mNotifManager);
   1575             expectMobileDefaults();
   1576 
   1577             mService.updateNetworks();
   1578 
   1579             assertEquals(0L, internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_JOBS));
   1580             assertEquals(0L, internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_MULTIPATH));
   1581         }
   1582 
   1583         // Roaming
   1584         {
   1585             final SubscriptionPlan plan = buildMonthlyDataPlan(
   1586                     ZonedDateTime.parse("2015-11-01T00:00:00.00Z"), BYTES_UNLIMITED);
   1587             mService.setSubscriptionPlans(TEST_SUB_ID, new SubscriptionPlan[]{plan},
   1588                     mServiceContext.getOpPackageName());
   1589 
   1590             reset(mTelephonyManager, mNetworkManager, mNotifManager);
   1591             expectMobileDefaults();
   1592             expectNetworkState(true /* roaming */);
   1593 
   1594             mService.updateNetworks();
   1595 
   1596             assertEquals(0L, internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_JOBS));
   1597             assertEquals(0L, internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_MULTIPATH));
   1598         }
   1599 
   1600         // Unlimited data plan
   1601         {
   1602             final SubscriptionPlan plan = buildMonthlyDataPlan(
   1603                     ZonedDateTime.parse("2015-11-01T00:00:00.00Z"), BYTES_UNLIMITED);
   1604             mService.setSubscriptionPlans(TEST_SUB_ID, new SubscriptionPlan[]{plan},
   1605                     mServiceContext.getOpPackageName());
   1606 
   1607             reset(mTelephonyManager, mNetworkManager, mNotifManager);
   1608             expectMobileDefaults();
   1609 
   1610             mService.updateNetworks();
   1611 
   1612             // 20MB/day, split equally between two types gives 10MB.
   1613             assertEquals(DataUnit.MEBIBYTES.toBytes(10),
   1614                     internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_JOBS));
   1615             assertEquals(DataUnit.MEBIBYTES.toBytes(10),
   1616                     internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_MULTIPATH));
   1617 
   1618             // Capabilities change to roaming
   1619             final ConnectivityManager.NetworkCallback callback = mNetworkCallbackCaptor.getValue();
   1620             assertNotNull(callback);
   1621             expectNetworkState(true /* roaming */);
   1622             callback.onCapabilitiesChanged(
   1623                     new Network(TEST_NET_ID),
   1624                     buildNetworkCapabilities(TEST_SUB_ID, true /* roaming */));
   1625 
   1626             assertEquals(0, internal.getSubscriptionOpportunisticQuota(
   1627                     new Network(TEST_NET_ID), NetworkPolicyManagerInternal.QUOTA_TYPE_MULTIPATH));
   1628         }
   1629     }
   1630 
   1631     /**
   1632      * Test that policy set of {null, NetworkPolicy, null} does not crash and restores the valid
   1633      * NetworkPolicy.
   1634      */
   1635     @Test
   1636     public void testSetNetworkPolicies_withNullPolicies_doesNotThrow() {
   1637         NetworkPolicy[] policies = new NetworkPolicy[3];
   1638         policies[1] = buildDefaultFakeMobilePolicy();
   1639         setNetworkPolicies(policies);
   1640 
   1641         assertNetworkPolicyEquals(DEFAULT_CYCLE_DAY, mDefaultWarningBytes, mDefaultLimitBytes,
   1642                 true);
   1643     }
   1644 
   1645     private SubscriptionPlan buildMonthlyDataPlan(ZonedDateTime start, long limitBytes) {
   1646         return SubscriptionPlan.Builder
   1647                 .createRecurringMonthly(start)
   1648                 .setDataLimit(limitBytes, LIMIT_BEHAVIOR_DISABLED)
   1649                 .build();
   1650     }
   1651 
   1652     private ApplicationInfo buildApplicationInfo(String label) {
   1653         final ApplicationInfo ai = new ApplicationInfo();
   1654         ai.nonLocalizedLabel = label;
   1655         return ai;
   1656     }
   1657 
   1658     private NetworkInfo buildNetworkInfo() {
   1659         final NetworkInfo ni = new NetworkInfo(ConnectivityManager.TYPE_MOBILE,
   1660                 TelephonyManager.NETWORK_TYPE_LTE, null, null);
   1661         ni.setDetailedState(NetworkInfo.DetailedState.CONNECTED, null, null);
   1662         return ni;
   1663     }
   1664 
   1665     private LinkProperties buildLinkProperties(String iface) {
   1666         final LinkProperties lp = new LinkProperties();
   1667         lp.setInterfaceName(iface);
   1668         return lp;
   1669     }
   1670 
   1671     private NetworkCapabilities buildNetworkCapabilities(int subId, boolean roaming) {
   1672         final NetworkCapabilities nc = new NetworkCapabilities();
   1673         nc.addTransportType(TRANSPORT_CELLULAR);
   1674         if (!roaming) {
   1675             nc.addCapability(NET_CAPABILITY_NOT_ROAMING);
   1676         }
   1677         nc.setNetworkSpecifier(new StringNetworkSpecifier(String.valueOf(subId)));
   1678         return nc;
   1679     }
   1680 
   1681     private NetworkPolicy buildDefaultFakeMobilePolicy() {
   1682         NetworkPolicy p = mService.buildDefaultMobilePolicy(FAKE_SUB_ID, FAKE_SUBSCRIBER_ID);
   1683         // set a deterministic cycle date
   1684         p.cycleRule = new RecurrenceRule(
   1685                 p.cycleRule.start.withDayOfMonth(DEFAULT_CYCLE_DAY),
   1686                 p.cycleRule.end, Period.ofMonths(1));
   1687         return p;
   1688     }
   1689 
   1690     private static NetworkPolicy buildFakeMobilePolicy(int cycleDay, long warningBytes,
   1691             long limitBytes, boolean inferred){
   1692         final NetworkTemplate template = buildTemplateMobileAll(FAKE_SUBSCRIBER_ID);
   1693         return new NetworkPolicy(template, cycleDay, new Time().timezone, warningBytes,
   1694                 limitBytes, SNOOZE_NEVER, SNOOZE_NEVER, true, inferred);
   1695     }
   1696 
   1697     private void assertNetworkPolicyEquals(int expectedCycleDay, long expectedWarningBytes,
   1698             long expectedLimitBytes, boolean expectedInferred) {
   1699         NetworkPolicy[] policies = mService.getNetworkPolicies(
   1700                 mServiceContext.getOpPackageName());
   1701         assertEquals("Unexpected number of network policies", 1, policies.length);
   1702         NetworkPolicy actualPolicy = policies[0];
   1703         NetworkPolicy expectedPolicy = buildFakeMobilePolicy(expectedCycleDay, expectedWarningBytes,
   1704                 expectedLimitBytes, expectedInferred);
   1705         assertEquals(expectedPolicy, actualPolicy);
   1706     }
   1707 
   1708     private static long parseTime(String time) {
   1709         return ZonedDateTime.parse(time).toInstant().toEpochMilli();
   1710     }
   1711 
   1712     private void setNetworkPolicies(NetworkPolicy... policies) {
   1713         mService.setNetworkPolicies(policies);
   1714     }
   1715 
   1716     private static NetworkState buildWifi() {
   1717         final NetworkInfo info = new NetworkInfo(TYPE_WIFI, 0, null, null);
   1718         info.setDetailedState(DetailedState.CONNECTED, null, null);
   1719         final LinkProperties prop = new LinkProperties();
   1720         prop.setInterfaceName(TEST_IFACE);
   1721         final NetworkCapabilities networkCapabilities = new NetworkCapabilities();
   1722         return new NetworkState(info, prop, networkCapabilities, null, null, TEST_SSID);
   1723     }
   1724 
   1725     private void expectHasInternetPermission(int uid, boolean hasIt) throws Exception {
   1726         when(mIpm.checkUidPermission(Manifest.permission.INTERNET, uid)).thenReturn(
   1727                 hasIt ? PackageManager.PERMISSION_GRANTED : PackageManager.PERMISSION_DENIED);
   1728     }
   1729 
   1730     private void expectNetworkState(boolean roaming) throws Exception {
   1731         when(mCarrierConfigManager.getConfigForSubId(eq(TEST_SUB_ID)))
   1732                 .thenReturn(CarrierConfigManager.getDefaultConfig());
   1733         when(mConnManager.getAllNetworkState()).thenReturn(new NetworkState[] {
   1734                 new NetworkState(buildNetworkInfo(),
   1735                         buildLinkProperties(TEST_IFACE),
   1736                         buildNetworkCapabilities(TEST_SUB_ID, roaming),
   1737                         new Network(TEST_NET_ID), TEST_IMSI, null)
   1738         });
   1739     }
   1740 
   1741     private void expectMobileDefaults() throws Exception {
   1742         when(mSubscriptionManager.getActiveSubscriptionIdList()).thenReturn(
   1743                 new int[] { TEST_SUB_ID });
   1744         when(mTelephonyManager.getSubscriberId(TEST_SUB_ID)).thenReturn(TEST_IMSI);
   1745         expectNetworkState(false /* roaming */);
   1746     }
   1747 
   1748     private void verifyAdvisePersistThreshold() throws Exception {
   1749         verify(mStatsService).advisePersistThreshold(anyLong());
   1750     }
   1751 
   1752     private static class TestAbstractFuture<T> extends AbstractFuture<T> {
   1753         @Override
   1754         public T get() throws InterruptedException, ExecutionException {
   1755             try {
   1756                 return get(5, TimeUnit.SECONDS);
   1757             } catch (TimeoutException e) {
   1758                 throw new RuntimeException(e);
   1759             }
   1760         }
   1761     }
   1762 
   1763     private static void assertTimeEquals(long expected, long actual) {
   1764         if (expected != actual) {
   1765             fail("expected " + formatTime(expected) + " but was actually " + formatTime(actual));
   1766         }
   1767     }
   1768 
   1769     private static String formatTime(long millis) {
   1770         return Instant.ofEpochMilli(millis) + " [" + millis + "]";
   1771     }
   1772 
   1773     private static void assertEqualsFuzzy(long expected, long actual, long fuzzy) {
   1774         final long low = expected - fuzzy;
   1775         final long high = expected + fuzzy;
   1776         if (actual < low || actual > high) {
   1777             fail("value " + formatTime(actual) + " is outside [" + formatTime(low) + ","
   1778                     + formatTime(high) + "]");
   1779         }
   1780     }
   1781 
   1782     private static void assertUnique(LinkedHashSet<Long> seen, Long value) {
   1783         if (!seen.add(value)) {
   1784             fail("found duplicate time " + value + " in series " + seen.toString());
   1785         }
   1786     }
   1787 
   1788     private static void assertNotificationType(int expected, String actualTag) {
   1789         assertEquals("notification type mismatch for '" + actualTag +"'",
   1790                 Integer.toString(expected), actualTag.substring(actualTag.lastIndexOf(':') + 1));
   1791     }
   1792 
   1793     private void assertUidPolicy(int uid, int expected) {
   1794         final int actual = mService.getUidPolicy(uid);
   1795         if (expected != actual) {
   1796             fail("Wrong policy for UID " + uid + ": expected " + uidPoliciesToString(expected)
   1797                     + ", actual " + uidPoliciesToString(actual));
   1798         }
   1799     }
   1800 
   1801     private void assertWhitelistUids(int... uids) {
   1802         assertContainsInAnyOrder(mService.getUidsWithPolicy(POLICY_ALLOW_METERED_BACKGROUND), uids);
   1803     }
   1804 
   1805     private void assertRestrictBackgroundOn() throws Exception {
   1806         assertTrue("restrictBackground should be set", mService.getRestrictBackground());
   1807     }
   1808 
   1809     private void assertRestrictBackgroundOff() throws Exception {
   1810         assertFalse("restrictBackground should not be set", mService.getRestrictBackground());
   1811     }
   1812 
   1813     private FutureIntent newRestrictBackgroundChangedFuture() {
   1814         return mServiceContext
   1815                 .nextBroadcastIntent(ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED);
   1816     }
   1817 
   1818     private void assertRestrictBackgroundChangedReceived(Future<Intent> future,
   1819             String expectedPackage) throws Exception {
   1820         final String action = ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED;
   1821         final Intent intent = future.get(5, TimeUnit.SECONDS);
   1822         assertNotNull("Didn't get a " + action + "intent in 5 seconds");
   1823         assertEquals("Wrong package on " + action + " intent", expectedPackage, intent.getPackage());
   1824     }
   1825 
   1826     // TODO: replace by Truth, Hamcrest, or a similar tool.
   1827     private void assertContainsInAnyOrder(int[] actual, int...expected) {
   1828         final StringBuilder errors = new StringBuilder();
   1829         if (actual.length != expected.length) {
   1830             errors.append("\tsize does not match\n");
   1831         }
   1832         final List<Integer> actualList =
   1833                 Arrays.stream(actual).boxed().collect(Collectors.<Integer>toList());
   1834         final List<Integer> expectedList =
   1835                 Arrays.stream(expected).boxed().collect(Collectors.<Integer>toList());
   1836         if (!actualList.containsAll(expectedList)) {
   1837             errors.append("\tmissing elements on actual list\n");
   1838         }
   1839         if (!expectedList.containsAll(actualList)) {
   1840             errors.append("\tmissing elements on expected list\n");
   1841         }
   1842         if (errors.length() > 0) {
   1843             fail("assertContainsInAnyOrder(expected=" + Arrays.toString(expected)
   1844                     + ", actual=" + Arrays.toString(actual) +") failed: \n" + errors);
   1845         }
   1846     }
   1847 
   1848     private long getElapsedRealtime() {
   1849         return mElapsedRealtime;
   1850     }
   1851 
   1852     private void setCurrentTimeMillis(long currentTimeMillis) {
   1853         RecurrenceRule.sClock = Clock.fixed(Instant.ofEpochMilli(currentTimeMillis),
   1854                 ZoneId.systemDefault());
   1855         mStartTime = currentTimeMillis;
   1856         mElapsedRealtime = 0L;
   1857     }
   1858 
   1859     private long currentTimeMillis() {
   1860         return mStartTime + mElapsedRealtime;
   1861     }
   1862 
   1863     private void incrementCurrentTime(long duration) {
   1864         mElapsedRealtime += duration;
   1865     }
   1866 
   1867     private FutureIntent mRestrictBackgroundChanged;
   1868 
   1869     private void setRestrictBackground(boolean flag) throws Exception {
   1870         mService.setRestrictBackground(flag);
   1871         // Sanity check.
   1872         assertEquals("restrictBackground not set", flag, mService.getRestrictBackground());
   1873     }
   1874 
   1875     /**
   1876      * Creates a mock and registers it to {@link LocalServices}.
   1877      */
   1878     private static <T> T addLocalServiceMock(Class<T> clazz) {
   1879         final T mock = mock(clazz);
   1880         LocalServices.addService(clazz, mock);
   1881         return mock;
   1882     }
   1883 
   1884     /**
   1885      * Custom Mockito answer used to verify async {@link INetworkPolicyListener} calls.
   1886      *
   1887      * <p>Typical usage:
   1888      * <pre><code>
   1889      *    mPolicyListener.expect().someCallback(any());
   1890      *    // do something on objects under test
   1891      *    mPolicyListener.waitAndVerify().someCallback(eq(expectedValue));
   1892      * </code></pre>
   1893      */
   1894     final class NetworkPolicyListenerAnswer implements Answer<Void> {
   1895         private CountDownLatch latch;
   1896         private final INetworkPolicyListener listener;
   1897 
   1898         NetworkPolicyListenerAnswer(NetworkPolicyManagerService service) {
   1899             this.listener = mock(INetworkPolicyListener.class);
   1900             // RemoteCallbackList needs a binder to use as key
   1901             when(listener.asBinder()).thenReturn(new Binder());
   1902             service.registerListener(listener);
   1903         }
   1904 
   1905         @Override
   1906         public Void answer(InvocationOnMock invocation) throws Throwable {
   1907             Log.d(TAG,"counting down on answer: " + invocation);
   1908             latch.countDown();
   1909             return null;
   1910         }
   1911 
   1912         INetworkPolicyListener expect() {
   1913             assertNull("expect() called before waitAndVerify()", latch);
   1914             latch = new CountDownLatch(1);
   1915             return doAnswer(this).when(listener);
   1916         }
   1917 
   1918         INetworkPolicyListener waitAndVerify() {
   1919             assertNotNull("waitAndVerify() called before expect()", latch);
   1920             try {
   1921                 assertTrue("callback not called in 5 seconds", latch.await(5, TimeUnit.SECONDS));
   1922             } catch (InterruptedException e) {
   1923                 fail("Thread interrupted before callback called");
   1924             } finally {
   1925                 latch = null;
   1926             }
   1927             return verify(listener, atLeastOnce());
   1928         }
   1929 
   1930         INetworkPolicyListener verifyNotCalled() {
   1931             return verify(listener, never());
   1932         }
   1933 
   1934     }
   1935 
   1936     private void setNetpolicyXml(Context context) throws Exception {
   1937         mPolicyDir = context.getFilesDir();
   1938         if (mPolicyDir.exists()) {
   1939             IoUtils.deleteContents(mPolicyDir);
   1940         }
   1941         if (!TextUtils.isEmpty(mNetpolicyXml)) {
   1942             final String assetPath = NETPOLICY_DIR + "/" + mNetpolicyXml;
   1943             final File netConfigFile = new File(mPolicyDir, "netpolicy.xml");
   1944             Log.d(TAG, "Creating " + netConfigFile + " from asset " + assetPath);
   1945             try (final InputStream in = context.getResources().getAssets().open(assetPath);
   1946                     final OutputStream out = new FileOutputStream(netConfigFile)) {
   1947                 Streams.copy(in, out);
   1948             }
   1949         }
   1950     }
   1951 
   1952     /**
   1953      * Annotation used to define the relative path of the {@code netpolicy.xml} file.
   1954      */
   1955     @Retention(RetentionPolicy.RUNTIME)
   1956     @Target(ElementType.METHOD)
   1957     public @interface NetPolicyXml {
   1958 
   1959         public String value() default "";
   1960 
   1961     }
   1962 
   1963     /**
   1964      * Rule used to set {@code mNetPolicyXml} according to the {@link NetPolicyXml} annotation.
   1965      */
   1966     public static class NetPolicyMethodRule implements MethodRule {
   1967 
   1968         @Override
   1969         public Statement apply(Statement base, FrameworkMethod method, Object target) {
   1970             for (Annotation annotation : method.getAnnotations()) {
   1971                 if ((annotation instanceof NetPolicyXml)) {
   1972                     final String path = ((NetPolicyXml) annotation).value();
   1973                     if (!path.isEmpty()) {
   1974                         ((NetworkPolicyManagerServiceTest) target).mNetpolicyXml = path;
   1975                         break;
   1976                     }
   1977                 }
   1978             }
   1979             return base;
   1980         }
   1981     }
   1982 }
   1983