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