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