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