• 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.app.ActivityManager.MAX_PROCESS_STATE;
22 import static android.app.ActivityManager.PROCESS_CAPABILITY_ALL;
23 import static android.app.ActivityManager.PROCESS_CAPABILITY_NONE;
24 import static android.app.ActivityManager.PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK;
25 import static android.app.ActivityManager.PROCESS_CAPABILITY_USER_RESTRICTED_NETWORK;
26 import static android.app.ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
27 import static android.app.ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
28 import static android.app.ActivityManager.PROCESS_STATE_SERVICE;
29 import static android.app.ActivityManager.PROCESS_STATE_TOP;
30 import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_DATA_SAVER;
31 import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_USER_RESTRICTED;
32 import static android.net.ConnectivityManager.BLOCKED_REASON_APP_BACKGROUND;
33 import static android.net.ConnectivityManager.BLOCKED_REASON_APP_STANDBY;
34 import static android.net.ConnectivityManager.BLOCKED_REASON_BATTERY_SAVER;
35 import static android.net.ConnectivityManager.BLOCKED_REASON_DOZE;
36 import static android.net.ConnectivityManager.BLOCKED_REASON_LOW_POWER_STANDBY;
37 import static android.net.ConnectivityManager.BLOCKED_REASON_NONE;
38 import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
39 import static android.net.ConnectivityManager.FIREWALL_CHAIN_BACKGROUND;
40 import static android.net.ConnectivityManager.FIREWALL_CHAIN_LOW_POWER_STANDBY;
41 import static android.net.ConnectivityManager.FIREWALL_CHAIN_RESTRICTED;
42 import static android.net.ConnectivityManager.TYPE_MOBILE;
43 import static android.net.ConnectivityManager.TYPE_WIFI;
44 import static android.net.INetd.FIREWALL_RULE_ALLOW;
45 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING;
46 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
47 import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
48 import static android.net.NetworkPolicy.LIMIT_DISABLED;
49 import static android.net.NetworkPolicy.SNOOZE_NEVER;
50 import static android.net.NetworkPolicy.WARNING_DISABLED;
51 import static android.net.NetworkPolicyManager.ALLOWED_METERED_REASON_FOREGROUND;
52 import static android.net.NetworkPolicyManager.ALLOWED_METERED_REASON_SYSTEM;
53 import static android.net.NetworkPolicyManager.ALLOWED_REASON_FOREGROUND;
54 import static android.net.NetworkPolicyManager.ALLOWED_REASON_LOW_POWER_STANDBY_ALLOWLIST;
55 import static android.net.NetworkPolicyManager.ALLOWED_REASON_NONE;
56 import static android.net.NetworkPolicyManager.ALLOWED_REASON_NOT_IN_BACKGROUND;
57 import static android.net.NetworkPolicyManager.ALLOWED_REASON_POWER_SAVE_ALLOWLIST;
58 import static android.net.NetworkPolicyManager.ALLOWED_REASON_POWER_SAVE_EXCEPT_IDLE_ALLOWLIST;
59 import static android.net.NetworkPolicyManager.ALLOWED_REASON_RESTRICTED_MODE_PERMISSIONS;
60 import static android.net.NetworkPolicyManager.ALLOWED_REASON_SYSTEM;
61 import static android.net.NetworkPolicyManager.ALLOWED_REASON_TOP;
62 import static android.net.NetworkPolicyManager.BACKGROUND_THRESHOLD_STATE;
63 import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT;
64 import static android.net.NetworkPolicyManager.FOREGROUND_THRESHOLD_STATE;
65 import static android.net.NetworkPolicyManager.POLICY_ALLOW_METERED_BACKGROUND;
66 import static android.net.NetworkPolicyManager.POLICY_NONE;
67 import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND;
68 import static android.net.NetworkPolicyManager.TOP_THRESHOLD_STATE;
69 import static android.net.NetworkPolicyManager.allowedReasonsToString;
70 import static android.net.NetworkPolicyManager.blockedReasonsToString;
71 import static android.net.NetworkPolicyManager.uidPoliciesToString;
72 import static android.net.NetworkPolicyManager.uidRulesToString;
73 import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK;
74 import static android.net.NetworkStats.METERED_NO;
75 import static android.net.NetworkStats.METERED_YES;
76 import static android.net.NetworkTemplate.MATCH_CARRIER;
77 import static android.net.NetworkTemplate.MATCH_MOBILE;
78 import static android.net.NetworkTemplate.MATCH_WIFI;
79 import static android.os.PowerExemptionManager.REASON_OTHER;
80 import static android.telephony.CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED;
81 import static android.telephony.CarrierConfigManager.DATA_CYCLE_THRESHOLD_DISABLED;
82 import static android.telephony.CarrierConfigManager.DATA_CYCLE_USE_PLATFORM_DEFAULT;
83 import static android.telephony.CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG;
84 import static android.telephony.CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG;
85 import static android.telephony.CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT;
86 import static android.telephony.SubscriptionPlan.BYTES_UNLIMITED;
87 import static android.telephony.SubscriptionPlan.LIMIT_BEHAVIOR_DISABLED;
88 
89 import static com.android.server.net.NetworkPolicyManagerInternal.QUOTA_TYPE_JOBS;
90 import static com.android.server.net.NetworkPolicyManagerInternal.QUOTA_TYPE_MULTIPATH;
91 import static com.android.server.net.NetworkPolicyManagerService.OPPORTUNISTIC_QUOTA_UNKNOWN;
92 import static com.android.server.net.NetworkPolicyManagerService.TYPE_LIMIT;
93 import static com.android.server.net.NetworkPolicyManagerService.TYPE_LIMIT_SNOOZED;
94 import static com.android.server.net.NetworkPolicyManagerService.TYPE_RAPID;
95 import static com.android.server.net.NetworkPolicyManagerService.TYPE_WARNING;
96 import static com.android.server.net.NetworkPolicyManagerService.UID_MSG_STATE_CHANGED;
97 import static com.android.server.net.NetworkPolicyManagerService.UidBlockedState.getEffectiveBlockedReasons;
98 import static com.android.server.net.NetworkPolicyManagerService.normalizeTemplate;
99 
100 import static org.junit.Assert.assertEquals;
101 import static org.junit.Assert.assertFalse;
102 import static org.junit.Assert.assertNotNull;
103 import static org.junit.Assert.assertNull;
104 import static org.junit.Assert.assertTrue;
105 import static org.junit.Assert.fail;
106 import static org.mockito.ArgumentMatchers.any;
107 import static org.mockito.ArgumentMatchers.anyBoolean;
108 import static org.mockito.ArgumentMatchers.anyInt;
109 import static org.mockito.ArgumentMatchers.anyLong;
110 import static org.mockito.ArgumentMatchers.anyString;
111 import static org.mockito.ArgumentMatchers.argThat;
112 import static org.mockito.ArgumentMatchers.eq;
113 import static org.mockito.ArgumentMatchers.isA;
114 import static org.mockito.Mockito.CALLS_REAL_METHODS;
115 import static org.mockito.Mockito.atLeast;
116 import static org.mockito.Mockito.atLeastOnce;
117 import static org.mockito.Mockito.clearInvocations;
118 import static org.mockito.Mockito.doAnswer;
119 import static org.mockito.Mockito.doNothing;
120 import static org.mockito.Mockito.mock;
121 import static org.mockito.Mockito.never;
122 import static org.mockito.Mockito.reset;
123 import static org.mockito.Mockito.times;
124 import static org.mockito.Mockito.verify;
125 import static org.mockito.Mockito.when;
126 
127 import android.Manifest;
128 import android.app.ActivityManager;
129 import android.app.ActivityManagerInternal;
130 import android.app.IActivityManager;
131 import android.app.IUidObserver;
132 import android.app.Notification;
133 import android.app.NotificationManager;
134 import android.app.usage.NetworkStats;
135 import android.app.usage.NetworkStatsManager;
136 import android.app.usage.UsageStatsManagerInternal;
137 import android.content.BroadcastReceiver;
138 import android.content.Context;
139 import android.content.Intent;
140 import android.content.IntentFilter;
141 import android.content.pm.ApplicationInfo;
142 import android.content.pm.IPackageManager;
143 import android.content.pm.PackageInfo;
144 import android.content.pm.PackageManager;
145 import android.content.pm.PackageManagerInternal;
146 import android.content.pm.Signature;
147 import android.content.pm.UserInfo;
148 import android.net.ConnectivityManager;
149 import android.net.INetworkManagementEventObserver;
150 import android.net.INetworkPolicyListener;
151 import android.net.LinkProperties;
152 import android.net.Network;
153 import android.net.NetworkCapabilities;
154 import android.net.NetworkPolicy;
155 import android.net.NetworkPolicyManager;
156 import android.net.NetworkStateSnapshot;
157 import android.net.NetworkTemplate;
158 import android.net.TelephonyNetworkSpecifier;
159 import android.net.wifi.WifiInfo;
160 import android.os.Binder;
161 import android.os.Build;
162 import android.os.Handler;
163 import android.os.INetworkManagementService;
164 import android.os.PersistableBundle;
165 import android.os.PowerExemptionManager;
166 import android.os.PowerManager;
167 import android.os.PowerManagerInternal;
168 import android.os.PowerSaveState;
169 import android.os.Process;
170 import android.os.RemoteException;
171 import android.os.SimpleClock;
172 import android.os.SystemClock;
173 import android.os.UserHandle;
174 import android.os.UserManager;
175 import android.platform.test.annotations.Presubmit;
176 import android.platform.test.annotations.RequiresFlagsDisabled;
177 import android.platform.test.annotations.RequiresFlagsEnabled;
178 import android.platform.test.flag.junit.CheckFlagsRule;
179 import android.platform.test.flag.junit.DeviceFlagsValueProvider;
180 import android.telephony.CarrierConfigManager;
181 import android.telephony.SubscriptionInfo;
182 import android.telephony.SubscriptionManager;
183 import android.telephony.SubscriptionPlan;
184 import android.telephony.TelephonyCallback;
185 import android.telephony.TelephonyManager;
186 import android.text.TextUtils;
187 import android.util.ArrayMap;
188 import android.util.ArraySet;
189 import android.util.DataUnit;
190 import android.util.Log;
191 import android.util.Pair;
192 import android.util.Range;
193 import android.util.RecurrenceRule;
194 import android.util.SparseArray;
195 import android.util.SparseIntArray;
196 
197 import androidx.test.InstrumentationRegistry;
198 import androidx.test.filters.FlakyTest;
199 import androidx.test.filters.MediumTest;
200 import androidx.test.runner.AndroidJUnit4;
201 
202 import com.android.internal.util.ArrayUtils;
203 import com.android.internal.util.test.BroadcastInterceptingContext;
204 import com.android.internal.util.test.BroadcastInterceptingContext.FutureIntent;
205 import com.android.internal.util.test.FsUtil;
206 import com.android.server.DeviceIdleInternal;
207 import com.android.server.LocalServices;
208 import com.android.server.pm.pkg.AndroidPackage;
209 import com.android.server.usage.AppStandbyInternal;
210 
211 import libcore.io.Streams;
212 
213 import org.junit.After;
214 import org.junit.Assume;
215 import org.junit.Before;
216 import org.junit.Rule;
217 import org.junit.Test;
218 import org.junit.rules.MethodRule;
219 import org.junit.runner.RunWith;
220 import org.junit.runners.model.FrameworkMethod;
221 import org.junit.runners.model.Statement;
222 import org.mockito.ArgumentCaptor;
223 import org.mockito.Mock;
224 import org.mockito.MockitoAnnotations;
225 import org.mockito.invocation.InvocationOnMock;
226 import org.mockito.stubbing.Answer;
227 
228 import java.io.File;
229 import java.io.FileOutputStream;
230 import java.io.InputStream;
231 import java.io.OutputStream;
232 import java.lang.annotation.Annotation;
233 import java.lang.annotation.ElementType;
234 import java.lang.annotation.Retention;
235 import java.lang.annotation.RetentionPolicy;
236 import java.lang.annotation.Target;
237 import java.time.Clock;
238 import java.time.Instant;
239 import java.time.Period;
240 import java.time.ZoneId;
241 import java.time.ZoneOffset;
242 import java.time.ZonedDateTime;
243 import java.util.ArrayList;
244 import java.util.Arrays;
245 import java.util.Calendar;
246 import java.util.HashMap;
247 import java.util.Iterator;
248 import java.util.LinkedHashSet;
249 import java.util.List;
250 import java.util.Map;
251 import java.util.Set;
252 import java.util.TimeZone;
253 import java.util.concurrent.CountDownLatch;
254 import java.util.concurrent.Future;
255 import java.util.concurrent.TimeUnit;
256 import java.util.function.Consumer;
257 import java.util.stream.Collectors;
258 
259 /**
260  * Tests for {@link NetworkPolicyManagerService}.
261  */
262 @RunWith(AndroidJUnit4.class)
263 @MediumTest
264 @Presubmit
265 public class NetworkPolicyManagerServiceTest {
266     private static final String TAG = "NetworkPolicyManagerServiceTest";
267 
268     @Rule
269     public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
270 
271     private static final long TEST_START = 1194220800000L;
272     private static final String TEST_IFACE = "test0";
273     private static final String TEST_WIFI_NETWORK_KEY = "TestWifiNetworkKey";
274     private static final String TEST_IMSI = "310210";
275     private static final int TEST_SUB_ID = 42;
276     private static final int TEST_SUB_ID2 = 24;
277     private static final Network TEST_NETWORK = mock(Network.class, CALLS_REAL_METHODS);
278 
279     private static NetworkTemplate sTemplateWifi = new NetworkTemplate.Builder(MATCH_WIFI)
280             .setWifiNetworkKeys(Set.of(TEST_WIFI_NETWORK_KEY)).build();
281     private static NetworkTemplate sTemplateCarrierMetered =
282             new NetworkTemplate.Builder(MATCH_CARRIER)
283                     .setSubscriberIds(Set.of(TEST_IMSI))
284                     .setMeteredness(METERED_YES).build();
285 
286     /**
287      * Path on assets where files used by {@link NetPolicyXml} are located.
288      */
289     private static final String NETPOLICY_DIR = "NetworkPolicyManagerServiceTest/netpolicy";
290     private static final String TIMEZONE_UTC = "UTC";
291 
292     private BroadcastInterceptingContext mServiceContext;
293     private File mPolicyDir;
294 
295     /**
296      * Relative path of the XML file that will be used as {@code netpolicy.xml}.
297      *
298      * <p>Typically set through a {@link NetPolicyXml} annotation in the test method.
299      */
300     private String mNetpolicyXml;
301 
302     private @Mock IActivityManager mActivityManager;
303     private @Mock INetworkManagementService mNetworkManager;
304     private @Mock ConnectivityManager mConnManager;
305     private @Mock NotificationManager mNotifManager;
306     private @Mock PackageManager mPackageManager;
307     private @Mock IPackageManager mIpm;
308     private @Mock SubscriptionManager mSubscriptionManager;
309     private @Mock CarrierConfigManager mCarrierConfigManager;
310     private @Mock TelephonyManager mTelephonyManager;
311     private @Mock UserManager mUserManager;
312     private @Mock NetworkStatsManager mStatsManager;
313     private @Mock PowerExemptionManager mPowerExemptionManager;
314     private TestDependencies mDeps;
315 
316     private ArgumentCaptor<ConnectivityManager.NetworkCallback> mNetworkCallbackCaptor =
317             ArgumentCaptor.forClass(ConnectivityManager.NetworkCallback.class);
318 
319     private TelephonyCallback.ActiveDataSubscriptionIdListener mActiveDataSubIdListener;
320 
321     private ActivityManagerInternal mActivityManagerInternal;
322     private PackageManagerInternal mPackageManagerInternal;
323 
324     private IUidObserver mUidObserver;
325     private INetworkManagementEventObserver mNetworkObserver;
326 
327     private NetworkPolicyListenerAnswer mPolicyListener;
328     private NetworkPolicyManagerService mService;
329 
330     private final ArraySet<BroadcastReceiver> mRegisteredReceivers = new ArraySet<>();
331     private BroadcastReceiver mPowerAllowlistReceiver;
332 
333     /**
334      * In some of the tests while initializing NetworkPolicyManagerService,
335      * ACTION_RESTRICT_BACKGROUND_CHANGED is broadcasted. This is for capturing that broadcast.
336      */
337     private FutureIntent mFutureIntent;
338 
339     private long mStartTime;
340     private long mElapsedRealtime;
341 
342     private static final int USER_ID = 0;
343     private static final int FAKE_SUB_ID = 3737373;
344     private static final String FAKE_SUBSCRIBER_ID = "FAKE_SUBSCRIBER_ID";
345     private static final int DEFAULT_CYCLE_DAY = 1;
346     private static final int INVALID_CARRIER_CONFIG_VALUE = -9999;
347     private long mDefaultWarningBytes; // filled in with the actual default before tests are run
348     private long mDefaultLimitBytes; // filled in with the actual default before tests are run
349     private PersistableBundle mCarrierConfig = CarrierConfigManager.getDefaultConfig();
350 
351     private static final int APP_ID_A = android.os.Process.FIRST_APPLICATION_UID + 4;
352     private static final int APP_ID_B = android.os.Process.FIRST_APPLICATION_UID + 8;
353     private static final int APP_ID_C = android.os.Process.FIRST_APPLICATION_UID + 15;
354     private static final int APP_ID_D = android.os.Process.FIRST_APPLICATION_UID + 16;
355     private static final int APP_ID_E = android.os.Process.FIRST_APPLICATION_UID + 23;
356     private static final int APP_ID_F = android.os.Process.FIRST_APPLICATION_UID + 42;
357 
358     private static final int UID_A = UserHandle.getUid(USER_ID, APP_ID_A);
359     private static final int UID_B = UserHandle.getUid(USER_ID, APP_ID_B);
360     private static final int UID_C = UserHandle.getUid(USER_ID, APP_ID_C);
361     private static final int UID_D = UserHandle.getUid(USER_ID, APP_ID_D);
362     private static final int UID_E = UserHandle.getUid(USER_ID, APP_ID_E);
363     private static final int UID_F = UserHandle.getUid(USER_ID, APP_ID_F);
364 
365     private static final String PKG_NAME_A = "name.is.A,pkg.A";
366     private static final String PKG_NAME_B = "name.is.B,pkg.B";
367     private static final String PKG_NAME_C = "name.is.C,pkg.C";
368 
369     public final @Rule NetPolicyMethodRule mNetPolicyXmlRule = new NetPolicyMethodRule();
370 
371     private final Clock mClock = new SimpleClock(ZoneOffset.UTC) {
372         @Override
373         public long millis() {
374             return currentTimeMillis();
375         }
376     };
377 
registerLocalServices()378     private void registerLocalServices() {
379         addLocalServiceMock(DeviceIdleInternal.class);
380         addLocalServiceMock(AppStandbyInternal.class);
381 
382         final UsageStatsManagerInternal usageStats =
383                 addLocalServiceMock(UsageStatsManagerInternal.class);
384         when(usageStats.getIdleUidsForUser(anyInt())).thenReturn(new int[]{});
385 
386         mActivityManagerInternal = addLocalServiceMock(ActivityManagerInternal.class);
387         mPackageManagerInternal = addLocalServiceMock(PackageManagerInternal.class);
388 
389         final PowerSaveState state = new PowerSaveState.Builder()
390                 .setBatterySaverEnabled(false).build();
391         final PowerManagerInternal pmInternal = addLocalServiceMock(PowerManagerInternal.class);
392         when(pmInternal.getLowPowerState(anyInt())).thenReturn(state);
393     }
394 
395     private class TestDependencies extends NetworkPolicyManagerService.Dependencies {
396         private final SparseArray<NetworkStats.Bucket> mMockedStats = new SparseArray<>();
397         private int mMockDefaultDataSubId;
398         private int mMockedActiveDataSubId;
399 
TestDependencies(Context context)400         TestDependencies(Context context) {
401             super(context);
402         }
403 
404         @Override
getNetworkTotalBytes(NetworkTemplate template, long start, long end)405         long getNetworkTotalBytes(NetworkTemplate template, long start, long end) {
406             int total = 0;
407             for (int i = 0; i < mMockedStats.size(); i++) {
408                 NetworkStats.Bucket bucket = mMockedStats.valueAt(i);
409                 total += bucket.getRxBytes() + bucket.getTxBytes();
410             }
411             return total;
412         }
413 
414         @Override
getNetworkUidBytes(NetworkTemplate template, long start, long end)415         List<NetworkStats.Bucket> getNetworkUidBytes(NetworkTemplate template, long start,
416                 long end) {
417             final List<NetworkStats.Bucket> ret = new ArrayList<>();
418             for (int i = 0; i < mMockedStats.size(); i++) {
419                 ret.add(mMockedStats.valueAt(i));
420             }
421             return ret;
422         }
423 
setMockedTotalBytes(int uid, long rxBytes, long txBytes)424         private void setMockedTotalBytes(int uid, long rxBytes, long txBytes) {
425             final NetworkStats.Bucket bucket = mock(NetworkStats.Bucket.class);
426             when(bucket.getUid()).thenReturn(uid);
427             when(bucket.getRxBytes()).thenReturn(rxBytes);
428             when(bucket.getTxBytes()).thenReturn(txBytes);
429             mMockedStats.set(uid, bucket);
430         }
431 
increaseMockedTotalBytes(int uid, long rxBytes, long txBytes)432         private void increaseMockedTotalBytes(int uid, long rxBytes, long txBytes) {
433             final NetworkStats.Bucket bucket = mMockedStats.get(uid);
434             setMockedTotalBytes(uid, bucket.getRxBytes() + rxBytes, bucket.getTxBytes() + txBytes);
435         }
436 
setDefaultAndActiveDataSubId(int defaultDataSubId, int activeDataSubId)437         void setDefaultAndActiveDataSubId(int defaultDataSubId, int activeDataSubId) {
438             mMockDefaultDataSubId = defaultDataSubId;
439             mMockedActiveDataSubId = activeDataSubId;
440         }
441 
442         @Override
getDefaultDataSubId()443         int getDefaultDataSubId() {
444             return mMockDefaultDataSubId;
445         }
446 
447         @Override
getActivateDataSubId()448         int getActivateDataSubId() {
449             return mMockedActiveDataSubId;
450         }
451     }
452 
453     // TODO: Use TestLooperManager instead.
454     /**
455      * Helper that leverages try-with-resources to pause dispatch of
456      * {@link #mHandlerThread} until released.
457      */
458     static class SyncBarrier implements AutoCloseable {
459         private final int mToken;
460         private Handler mHandler;
461 
SyncBarrier(Handler handler)462         SyncBarrier(Handler handler) {
463             mHandler = handler;
464             mToken = mHandler.getLooper().getQueue().postSyncBarrier();
465         }
466 
467         @Override
close()468         public void close() throws Exception {
469             mHandler.getLooper().getQueue().removeSyncBarrier(mToken);
470         }
471     }
472 
473     @Before
callSystemReady()474     public void callSystemReady() throws Exception {
475         MockitoAnnotations.initMocks(this);
476         when(mPowerExemptionManager.getAllowListedAppIds(anyBoolean())).thenReturn(new int[0]);
477 
478         final Context context = InstrumentationRegistry.getContext();
479 
480         setCurrentTimeMillis(TEST_START);
481 
482         registerLocalServices();
483         // Intercept various broadcasts, and pretend that uids have packages.
484         // Also return mock service instances for a few critical services.
485         mServiceContext = new BroadcastInterceptingContext(context) {
486             @Override
487             public PackageManager getPackageManager() {
488                 return mPackageManager;
489             }
490 
491             @Override
492             public void startActivity(Intent intent) {
493                 // ignored
494             }
495 
496             @Override
497             public Object getSystemService(String name) {
498                 switch (name) {
499                     case Context.TELEPHONY_SUBSCRIPTION_SERVICE:
500                         return mSubscriptionManager;
501                     case Context.CARRIER_CONFIG_SERVICE:
502                         return mCarrierConfigManager;
503                     case Context.TELEPHONY_SERVICE:
504                         return mTelephonyManager;
505                     case Context.NOTIFICATION_SERVICE:
506                         return mNotifManager;
507                     case Context.CONNECTIVITY_SERVICE:
508                         return mConnManager;
509                     case Context.USER_SERVICE:
510                         return mUserManager;
511                     case Context.NETWORK_STATS_SERVICE:
512                         return mStatsManager;
513                     case Context.POWER_EXEMPTION_SERVICE:
514                         return mPowerExemptionManager;
515                     default:
516                         return super.getSystemService(name);
517                 }
518             }
519 
520             @Override
521             public void enforceCallingOrSelfPermission(String permission, String message) {
522                 // Assume that we're AID_SYSTEM
523             }
524 
525             @Override
526             public Intent registerReceiver(BroadcastReceiver receiver,
527                     IntentFilter filter, String broadcastPermission, Handler scheduler) {
528                 if (filter.hasAction(PowerManager.ACTION_POWER_SAVE_WHITELIST_CHANGED)) {
529                     mPowerAllowlistReceiver = receiver;
530                 }
531                 mRegisteredReceivers.add(receiver);
532                 return super.registerReceiver(receiver, filter, broadcastPermission, scheduler);
533             }
534 
535             @Override
536             public Intent registerReceiverForAllUsers(BroadcastReceiver receiver,
537                     IntentFilter filter, String broadcastPermission, Handler scheduler) {
538                 mRegisteredReceivers.add(receiver);
539                 return super.registerReceiverForAllUsers(receiver, filter, broadcastPermission,
540                         scheduler);
541             }
542         };
543 
544         setNetpolicyXml(context);
545 
546         doAnswer(new Answer<Void>() {
547             @Override
548             public Void answer(InvocationOnMock invocation) throws Throwable {
549                 mUidObserver = (IUidObserver) invocation.getArguments()[0];
550                 Log.d(TAG, "set mUidObserver to " + mUidObserver);
551                 return null;
552             }
553         }).when(mActivityManagerInternal).registerNetworkPolicyUidObserver(any(),
554                 anyInt(), anyInt(), any(String.class));
555 
556         mFutureIntent = newRestrictBackgroundChangedFuture();
557         mDeps = new TestDependencies(mServiceContext);
558         mService = new NetworkPolicyManagerService(mServiceContext, mActivityManager,
559                 mNetworkManager, mIpm, mClock, mPolicyDir, true, mDeps);
560         mService.bindConnectivityManager();
561         mPolicyListener = new NetworkPolicyListenerAnswer(mService);
562 
563         // Sets some common expectations.
564         when(mPackageManager.getPackageInfo(anyString(), anyInt())).thenAnswer(
565                 new Answer<PackageInfo>() {
566 
567                     @Override
568                     public PackageInfo answer(InvocationOnMock invocation) throws Throwable {
569                         final String packageName = (String) invocation.getArguments()[0];
570                         final PackageInfo info = new PackageInfo();
571                         final Signature signature;
572                         if ("android".equals(packageName)) {
573                             signature = new Signature("F00D");
574                         } else {
575                             signature = new Signature("DEAD");
576                         }
577                         info.signatures = new Signature[] {
578                             signature
579                         };
580                         return info;
581                     }
582                 });
583         when(mPackageManager.getApplicationInfoAsUser(anyString(), anyInt(), anyInt()))
584                 .thenReturn(new ApplicationInfo());
585         when(mPackageManager.getPackagesForUid(UID_A)).thenReturn(new String[] {PKG_NAME_A});
586         when(mPackageManager.getPackagesForUid(UID_B)).thenReturn(new String[] {PKG_NAME_B});
587         when(mPackageManager.getPackagesForUid(UID_C)).thenReturn(new String[] {PKG_NAME_C});
588         when(mPackageManager.getApplicationInfo(eq(PKG_NAME_A), anyInt()))
589                 .thenReturn(buildApplicationInfo(PKG_NAME_A, UID_A));
590         when(mPackageManager.getApplicationInfo(eq(PKG_NAME_B), anyInt()))
591                 .thenReturn(buildApplicationInfo(PKG_NAME_B, UID_B));
592         when(mPackageManager.getApplicationInfo(eq(PKG_NAME_C), anyInt()))
593                 .thenReturn(buildApplicationInfo(PKG_NAME_C, UID_C));
594         doAnswer(arg -> {
595             final Consumer<AndroidPackage> consumer =
596                     (Consumer<AndroidPackage>) arg.getArguments()[0];
597             for (AndroidPackage androidPackage : buildInstalledPackageList()) {
598                 consumer.accept(androidPackage);
599             }
600             return null;
601         }).when(mPackageManagerInternal).forEachInstalledPackage(
602                 any(Consumer.class), anyInt());
603         when(mUserManager.getUsers()).thenReturn(buildUserInfoList());
604         when(mNetworkManager.isBandwidthControlEnabled()).thenReturn(true);
605         when(mNetworkManager.setDataSaverModeEnabled(anyBoolean())).thenReturn(true);
606         doNothing().when(mConnManager)
607                 .registerNetworkCallback(any(), mNetworkCallbackCaptor.capture());
608 
609         // Create the expected carrier config
610         mCarrierConfig.putBoolean(CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL, true);
611 
612         // Prepare NPMS.
613         mService.systemReady(mService.networkScoreAndNetworkManagementServiceReady());
614 
615         // catch INetworkManagementEventObserver during systemReady()
616         final ArgumentCaptor<INetworkManagementEventObserver> networkObserver =
617                 ArgumentCaptor.forClass(INetworkManagementEventObserver.class);
618         verify(mNetworkManager).registerObserver(networkObserver.capture());
619         mNetworkObserver = networkObserver.getValue();
620 
621         // Catch UsageCallback during systemReady(). Simulate NetworkStatsService triggered
622         // stats updated callback to signal its readiness.
623         final ArgumentCaptor<NetworkStatsManager.UsageCallback> usageObserver =
624                 ArgumentCaptor.forClass(NetworkStatsManager.UsageCallback.class);
625         verify(mStatsManager, times(2))
626                 .registerUsageCallback(any(), anyLong(), any(), usageObserver.capture());
627         // It doesn't matter which of the observers is returned here.
628         usageObserver.getValue().onThresholdReached(
629                 new NetworkTemplate.Builder(MATCH_MOBILE).build());
630 
631         NetworkPolicy defaultPolicy = mService.buildDefaultCarrierPolicy(0, "");
632         mDefaultWarningBytes = defaultPolicy.warningBytes;
633         mDefaultLimitBytes = defaultPolicy.limitBytes;
634 
635         // Catch TelephonyCallback during systemReady().
636         ArgumentCaptor<TelephonyCallback> telephonyCallbackArgumentCaptor =
637                 ArgumentCaptor.forClass(TelephonyCallback.class);
638         verify(mTelephonyManager).registerTelephonyCallback(any(),
639                 telephonyCallbackArgumentCaptor.capture());
640         mActiveDataSubIdListener = (TelephonyCallback.ActiveDataSubscriptionIdListener)
641                 telephonyCallbackArgumentCaptor.getValue();
642     }
643 
644     @After
removeFiles()645     public void removeFiles() throws Exception {
646         for (File file : mPolicyDir.listFiles()) {
647             file.delete();
648         }
649     }
650 
651     @After
unregisterLocalServices()652     public void unregisterLocalServices() throws Exception {
653         // Registered by NetworkPolicyManagerService's constructor.
654         LocalServices.removeServiceForTest(NetworkPolicyManagerInternal.class);
655 
656         // Added in registerLocalServices()
657         LocalServices.removeServiceForTest(ActivityManagerInternal.class);
658         LocalServices.removeServiceForTest(PowerManagerInternal.class);
659         LocalServices.removeServiceForTest(DeviceIdleInternal.class);
660         LocalServices.removeServiceForTest(AppStandbyInternal.class);
661         LocalServices.removeServiceForTest(UsageStatsManagerInternal.class);
662         LocalServices.removeServiceForTest(PackageManagerInternal.class);
663     }
664 
665     @After
resetClock()666     public void resetClock() throws Exception {
667         RecurrenceRule.sClock = Clock.systemDefaultZone();
668     }
669 
670     @After
unregisterReceivers()671     public void unregisterReceivers() throws Exception {
672         for (BroadcastReceiver receiver : mRegisteredReceivers) {
673             mServiceContext.unregisterReceiver(receiver);
674         }
675     }
676 
677     @Test
testTurnRestrictBackgroundOn()678     public void testTurnRestrictBackgroundOn() throws Exception {
679         assertRestrictBackgroundOff();
680         final FutureIntent futureIntent = newRestrictBackgroundChangedFuture();
681         setRestrictBackground(true);
682         assertRestrictBackgroundChangedReceived(futureIntent, null);
683     }
684 
685     @Test
686     @NetPolicyXml("restrict-background-on.xml")
testTurnRestrictBackgroundOff()687     public void testTurnRestrictBackgroundOff() throws Exception {
688         assertRestrictBackgroundOn();
689         assertRestrictBackgroundChangedReceived(mFutureIntent, null);
690         final FutureIntent futureIntent = newRestrictBackgroundChangedFuture();
691         setRestrictBackground(false);
692         assertRestrictBackgroundChangedReceived(futureIntent, null);
693     }
694 
695     /**
696      * Adds an app to allowlist when restrict background is on - app should receive an intent.
697      */
698     @Test
699     @NetPolicyXml("restrict-background-on.xml")
testAddRestrictBackgroundAllowlist_restrictBackgroundOn()700     public void testAddRestrictBackgroundAllowlist_restrictBackgroundOn() throws Exception {
701         assertRestrictBackgroundOn();
702         assertRestrictBackgroundChangedReceived(mFutureIntent, null);
703         addRestrictBackgroundAllowlist(true);
704     }
705 
706     /**
707      * Adds an app to allowlist when restrict background is off - app should not receive an intent.
708      */
709     @Test
testAddRestrictBackgroundAllowlist_restrictBackgroundOff()710     public void testAddRestrictBackgroundAllowlist_restrictBackgroundOff() throws Exception {
711         assertRestrictBackgroundOff();
712         addRestrictBackgroundAllowlist(false);
713     }
714 
addRestrictBackgroundAllowlist(boolean expectIntent)715     private void addRestrictBackgroundAllowlist(boolean expectIntent) throws Exception {
716         assertRestrictBackgroundAllowedUids();
717         assertUidPolicy(UID_A, POLICY_NONE);
718 
719         final FutureIntent futureIntent = newRestrictBackgroundChangedFuture();
720         mPolicyListener.expect().onUidPoliciesChanged(anyInt(), anyInt());
721 
722         mService.setUidPolicy(UID_A, POLICY_ALLOW_METERED_BACKGROUND);
723 
724         assertRestrictBackgroundAllowedUids(UID_A);
725         assertUidPolicy(UID_A, POLICY_ALLOW_METERED_BACKGROUND);
726         mPolicyListener.waitAndVerify()
727                 .onUidPoliciesChanged(APP_ID_A, POLICY_ALLOW_METERED_BACKGROUND);
728         if (expectIntent) {
729             assertRestrictBackgroundChangedReceived(futureIntent, PKG_NAME_A);
730         } else {
731             futureIntent.assertNotReceived();
732         }
733     }
734 
735     /**
736      * Removes an app from allowlist when restrict background is on - app should receive an intent.
737      */
738     @Test
739     @NetPolicyXml("uidA-allowed-restrict-background-on.xml")
testRemoveRestrictBackgroundAllowlist_restrictBackgroundOn()740     public void testRemoveRestrictBackgroundAllowlist_restrictBackgroundOn() throws Exception {
741         assertRestrictBackgroundOn();
742         assertRestrictBackgroundChangedReceived(mFutureIntent, null);
743         removeRestrictBackgroundAllowlist(true);
744     }
745 
746     /**
747      * Removes an app from allowlist when restrict background is off - app should not
748      * receive an intent.
749      */
750     @Test
751     @NetPolicyXml("uidA-allowed-restrict-background-off.xml")
testRemoveRestrictBackgroundAllowlist_restrictBackgroundOff()752     public void testRemoveRestrictBackgroundAllowlist_restrictBackgroundOff() throws Exception {
753         assertRestrictBackgroundOff();
754         removeRestrictBackgroundAllowlist(false);
755     }
756 
757     @Test
testLowPowerModeObserver_ListenersRegistered()758     public void testLowPowerModeObserver_ListenersRegistered()
759             throws Exception {
760         PowerManagerInternal pmInternal = LocalServices.getService(PowerManagerInternal.class);
761 
762         verify(pmInternal, atLeast(2)).registerLowPowerModeObserver(any());
763     }
764 
765     @Test
updateRestrictBackgroundByLowPowerMode_RestrictOnBeforeBsm_RestrictOnAfterBsm()766     public void updateRestrictBackgroundByLowPowerMode_RestrictOnBeforeBsm_RestrictOnAfterBsm()
767             throws Exception {
768         setRestrictBackground(true);
769         PowerSaveState stateOn = new PowerSaveState.Builder()
770                 .setGlobalBatterySaverEnabled(true)
771                 .setBatterySaverEnabled(false)
772                 .build();
773         mService.updateRestrictBackgroundByLowPowerModeUL(stateOn);
774 
775         // RestrictBackground should be on even though battery saver want to turn it off
776         assertTrue(mService.getRestrictBackground());
777 
778         PowerSaveState stateOff = new PowerSaveState.Builder()
779                 .setGlobalBatterySaverEnabled(false)
780                 .setBatterySaverEnabled(false)
781                 .build();
782         mService.updateRestrictBackgroundByLowPowerModeUL(stateOff);
783 
784         // RestrictBackground should be on, as before.
785         assertTrue(mService.getRestrictBackground());
786 
787         stateOn = new PowerSaveState.Builder()
788                 .setGlobalBatterySaverEnabled(true)
789                 .setBatterySaverEnabled(true)
790                 .build();
791         mService.updateRestrictBackgroundByLowPowerModeUL(stateOn);
792 
793         // RestrictBackground should be on.
794         assertTrue(mService.getRestrictBackground());
795 
796         stateOff = new PowerSaveState.Builder()
797                 .setGlobalBatterySaverEnabled(false)
798                 .setBatterySaverEnabled(false)
799                 .build();
800         mService.updateRestrictBackgroundByLowPowerModeUL(stateOff);
801 
802         // RestrictBackground should be on, as it was enabled manually before battery saver.
803         assertTrue(mService.getRestrictBackground());
804     }
805 
806     @Test
updateRestrictBackgroundByLowPowerMode_RestrictOffBeforeBsm_RestrictOffAfterBsm()807     public void updateRestrictBackgroundByLowPowerMode_RestrictOffBeforeBsm_RestrictOffAfterBsm()
808             throws Exception {
809         setRestrictBackground(false);
810         PowerSaveState stateOn = new PowerSaveState.Builder()
811                 .setGlobalBatterySaverEnabled(true)
812                 .setBatterySaverEnabled(true)
813                 .build();
814 
815         mService.updateRestrictBackgroundByLowPowerModeUL(stateOn);
816 
817         // RestrictBackground should be turned on because of battery saver
818         assertTrue(mService.getRestrictBackground());
819 
820         PowerSaveState stateOff = new PowerSaveState.Builder()
821                 .setGlobalBatterySaverEnabled(false)
822                 .setBatterySaverEnabled(false)
823                 .build();
824         mService.updateRestrictBackgroundByLowPowerModeUL(stateOff);
825 
826         // RestrictBackground should be off, following its previous state
827         assertFalse(mService.getRestrictBackground());
828 
829         PowerSaveState stateOnRestrictOff = new PowerSaveState.Builder()
830                 .setGlobalBatterySaverEnabled(true)
831                 .setBatterySaverEnabled(false)
832                 .build();
833 
834         mService.updateRestrictBackgroundByLowPowerModeUL(stateOnRestrictOff);
835 
836         assertFalse(mService.getRestrictBackground());
837 
838         mService.updateRestrictBackgroundByLowPowerModeUL(stateOff);
839 
840         // RestrictBackground should still be off.
841         assertFalse(mService.getRestrictBackground());
842     }
843 
844     @Test
updateRestrictBackgroundByLowPowerMode_StatusChangedInBsm_DoNotRestore()845     public void updateRestrictBackgroundByLowPowerMode_StatusChangedInBsm_DoNotRestore()
846             throws Exception {
847         setRestrictBackground(true);
848         PowerSaveState stateOn = new PowerSaveState.Builder()
849                 .setGlobalBatterySaverEnabled(true)
850                 .setBatterySaverEnabled(true)
851                 .build();
852         mService.updateRestrictBackgroundByLowPowerModeUL(stateOn);
853 
854         // RestrictBackground should still be on
855         assertTrue(mService.getRestrictBackground());
856 
857         // User turns off RestrictBackground manually
858         setRestrictBackground(false);
859         // RestrictBackground should be off because user changed it manually
860         assertFalse(mService.getRestrictBackground());
861 
862         PowerSaveState stateOff = new PowerSaveState.Builder()
863                 .setGlobalBatterySaverEnabled(false)
864                 .setBatterySaverEnabled(false)
865                 .build();
866         mService.updateRestrictBackgroundByLowPowerModeUL(stateOff);
867 
868         // RestrictBackground should remain off.
869         assertFalse(mService.getRestrictBackground());
870     }
871 
872     @Test
updateRestrictBackgroundByLowPowerMode_RestrictOnWithGlobalOff()873     public void updateRestrictBackgroundByLowPowerMode_RestrictOnWithGlobalOff()
874             throws Exception {
875         setRestrictBackground(false);
876         PowerSaveState stateOn = new PowerSaveState.Builder()
877                 .setGlobalBatterySaverEnabled(false)
878                 .setBatterySaverEnabled(true)
879                 .build();
880 
881         mService.updateRestrictBackgroundByLowPowerModeUL(stateOn);
882 
883         // RestrictBackground should be turned on because of battery saver.
884         assertTrue(mService.getRestrictBackground());
885 
886         PowerSaveState stateRestrictOff = new PowerSaveState.Builder()
887                 .setGlobalBatterySaverEnabled(true)
888                 .setBatterySaverEnabled(false)
889                 .build();
890         mService.updateRestrictBackgroundByLowPowerModeUL(stateRestrictOff);
891 
892         // RestrictBackground should be off, returning to its state before battery saver's change.
893         assertFalse(mService.getRestrictBackground());
894 
895         PowerSaveState stateOff = new PowerSaveState.Builder()
896                 .setGlobalBatterySaverEnabled(false)
897                 .setBatterySaverEnabled(false)
898                 .build();
899         mService.updateRestrictBackgroundByLowPowerModeUL(stateOff);
900 
901         // RestrictBackground should still be off, back in its pre-battery saver state.
902         assertFalse(mService.getRestrictBackground());
903     }
904 
removeRestrictBackgroundAllowlist(boolean expectIntent)905     private void removeRestrictBackgroundAllowlist(boolean expectIntent) throws Exception {
906         assertRestrictBackgroundAllowedUids(UID_A);
907         assertUidPolicy(UID_A, POLICY_ALLOW_METERED_BACKGROUND);
908 
909         final FutureIntent futureIntent = newRestrictBackgroundChangedFuture();
910         mPolicyListener.expect().onUidPoliciesChanged(anyInt(), anyInt());
911 
912         mService.setUidPolicy(UID_A, POLICY_NONE);
913 
914         assertRestrictBackgroundAllowedUids();
915         assertUidPolicy(UID_A, POLICY_NONE);
916         mPolicyListener.waitAndVerify().onUidPoliciesChanged(APP_ID_A, POLICY_NONE);
917         if (expectIntent) {
918             assertRestrictBackgroundChangedReceived(futureIntent, PKG_NAME_A);
919         } else {
920             futureIntent.assertNotReceived();
921         }
922     }
923 
924     /**
925      * Adds an app to denylist when restrict background is on - app should not receive an intent.
926      */
927     @Test
928     @NetPolicyXml("restrict-background-on.xml")
testAddRestrictBackgroundDenylist_restrictBackgroundOn()929     public void testAddRestrictBackgroundDenylist_restrictBackgroundOn() throws Exception {
930         assertRestrictBackgroundOn();
931         assertRestrictBackgroundChangedReceived(mFutureIntent, null);
932         addRestrictBackgroundDenylist(false);
933     }
934 
935     /**
936      * Adds an app to denylist when restrict background is off - app should receive an intent.
937      */
938     @Test
testAddRestrictBackgroundDenylist_restrictBackgroundOff()939     public void testAddRestrictBackgroundDenylist_restrictBackgroundOff() throws Exception {
940         assertRestrictBackgroundOff();
941         addRestrictBackgroundDenylist(true);
942     }
943 
addRestrictBackgroundDenylist(boolean expectIntent)944     private void addRestrictBackgroundDenylist(boolean expectIntent) throws Exception {
945         assertUidPolicy(UID_A, POLICY_NONE);
946         final FutureIntent futureIntent = newRestrictBackgroundChangedFuture();
947         mPolicyListener.expect().onUidPoliciesChanged(anyInt(), anyInt());
948 
949         mService.setUidPolicy(UID_A, POLICY_REJECT_METERED_BACKGROUND);
950 
951         assertUidPolicy(UID_A, POLICY_REJECT_METERED_BACKGROUND);
952         mPolicyListener.waitAndVerify()
953                 .onUidPoliciesChanged(APP_ID_A, POLICY_REJECT_METERED_BACKGROUND);
954         if (expectIntent) {
955             assertRestrictBackgroundChangedReceived(futureIntent, PKG_NAME_A);
956         } else {
957             futureIntent.assertNotReceived();
958         }
959     }
960 
961     /**
962      * Removes an app from denylist when restrict background is on - app should not
963      * receive an intent.
964      */
965     @Test
966     @NetPolicyXml("uidA-denied-restrict-background-on.xml")
testRemoveRestrictBackgroundDenylist_restrictBackgroundOn()967     public void testRemoveRestrictBackgroundDenylist_restrictBackgroundOn() throws Exception {
968         assertRestrictBackgroundOn();
969         assertRestrictBackgroundChangedReceived(mFutureIntent, null);
970         removeRestrictBackgroundDenylist(false);
971     }
972 
973     /**
974      * Removes an app from denylist when restrict background is off - app should
975      * receive an intent.
976      */
977     @Test
978     @NetPolicyXml("uidA-denied-restrict-background-off.xml")
testRemoveRestrictBackgroundDenylist_restrictBackgroundOff()979     public void testRemoveRestrictBackgroundDenylist_restrictBackgroundOff() throws Exception {
980         assertRestrictBackgroundOff();
981         removeRestrictBackgroundDenylist(true);
982     }
983 
removeRestrictBackgroundDenylist(boolean expectIntent)984     private void removeRestrictBackgroundDenylist(boolean expectIntent) throws Exception {
985         assertUidPolicy(UID_A, POLICY_REJECT_METERED_BACKGROUND);
986         final FutureIntent futureIntent = newRestrictBackgroundChangedFuture();
987         mPolicyListener.expect().onUidPoliciesChanged(anyInt(), anyInt());
988 
989         mService.setUidPolicy(UID_A, POLICY_NONE);
990 
991         assertUidPolicy(UID_A, POLICY_NONE);
992         mPolicyListener.waitAndVerify()
993                 .onUidPoliciesChanged(APP_ID_A, POLICY_NONE);
994         if (expectIntent) {
995             assertRestrictBackgroundChangedReceived(futureIntent, PKG_NAME_A);
996         } else {
997             futureIntent.assertNotReceived();
998         }
999     }
1000 
1001     @Test
1002     @NetPolicyXml("uidA-denied-restrict-background-on.xml")
testDeniedAppIsNotNotifiedWhenRestrictBackgroundIsOn()1003     public void testDeniedAppIsNotNotifiedWhenRestrictBackgroundIsOn() throws Exception {
1004         assertRestrictBackgroundOn();
1005         assertRestrictBackgroundChangedReceived(mFutureIntent, null);
1006         assertUidPolicy(UID_A, POLICY_REJECT_METERED_BACKGROUND);
1007 
1008         final FutureIntent futureIntent = newRestrictBackgroundChangedFuture();
1009         setRestrictBackground(true);
1010         futureIntent.assertNotReceived();
1011     }
1012 
1013     @Test
1014     @NetPolicyXml("uidA-allowed-restrict-background-on.xml")
testAllowedAppIsNotNotifiedWhenRestrictBackgroundIsOn()1015     public void testAllowedAppIsNotNotifiedWhenRestrictBackgroundIsOn() throws Exception {
1016         assertRestrictBackgroundOn();
1017         assertRestrictBackgroundChangedReceived(mFutureIntent, null);
1018         assertRestrictBackgroundAllowedUids(UID_A);
1019 
1020         final FutureIntent futureIntent = newRestrictBackgroundChangedFuture();
1021         setRestrictBackground(true);
1022         futureIntent.assertNotReceived();
1023     }
1024 
1025     @Test
1026     @NetPolicyXml("uidA-allowed-restrict-background-on.xml")
testAllowedAppIsNotifiedWhenDenylisted()1027     public void testAllowedAppIsNotifiedWhenDenylisted() throws Exception {
1028         assertRestrictBackgroundOn();
1029         assertRestrictBackgroundChangedReceived(mFutureIntent, null);
1030         assertRestrictBackgroundAllowedUids(UID_A);
1031 
1032         final FutureIntent futureIntent = newRestrictBackgroundChangedFuture();
1033         mService.setUidPolicy(UID_A, POLICY_REJECT_METERED_BACKGROUND);
1034         assertRestrictBackgroundChangedReceived(futureIntent, PKG_NAME_A);
1035     }
1036 
1037     @Test
1038     @NetPolicyXml("restrict-background-lists-allowlist-format.xml")
testRestrictBackgroundLists_allowlistFormat()1039     public void testRestrictBackgroundLists_allowlistFormat() throws Exception {
1040         restrictBackgroundListsTest();
1041     }
1042 
1043     @Test
1044     @NetPolicyXml("restrict-background-lists-uid-policy-format.xml")
testRestrictBackgroundLists_uidPolicyFormat()1045     public void testRestrictBackgroundLists_uidPolicyFormat() throws Exception {
1046         restrictBackgroundListsTest();
1047     }
1048 
restrictBackgroundListsTest()1049     private void restrictBackgroundListsTest() throws Exception {
1050         // UIds that are in allowlist.
1051         assertRestrictBackgroundAllowedUids(UID_A, UID_B, UID_C);
1052         assertUidPolicy(UID_A, POLICY_ALLOW_METERED_BACKGROUND);
1053         assertUidPolicy(UID_B, POLICY_ALLOW_METERED_BACKGROUND);
1054         assertUidPolicy(UID_C, POLICY_ALLOW_METERED_BACKGROUND);
1055 
1056         // UIDs that are in denylist.
1057         assertUidPolicy(UID_D, POLICY_NONE);
1058         assertUidPolicy(UID_E, POLICY_REJECT_METERED_BACKGROUND);
1059 
1060         // UIDS that have legacy policies.
1061         assertUidPolicy(UID_F, 2); // POLICY_ALLOW_BACKGROUND_BATTERY_SAVE
1062 
1063         // Remove an uid from allowlist.
1064         mService.setUidPolicy(UID_A, POLICY_NONE);
1065         assertUidPolicy(UID_A, POLICY_NONE);
1066         assertRestrictBackgroundAllowedUids(UID_B, UID_C);
1067 
1068         // Add an app to allowlist which is currently in denylist.
1069         mService.setUidPolicy(UID_E, POLICY_ALLOW_METERED_BACKGROUND);
1070         assertUidPolicy(UID_E, POLICY_ALLOW_METERED_BACKGROUND);
1071         assertRestrictBackgroundAllowedUids(UID_B, UID_C, UID_E);
1072 
1073         // Add an app to denylist when is currently in allowlist.
1074         mService.setUidPolicy(UID_B, POLICY_REJECT_METERED_BACKGROUND);
1075         assertUidPolicy(UID_B, POLICY_REJECT_METERED_BACKGROUND);
1076         assertRestrictBackgroundAllowedUids(UID_C, UID_E);
1077     }
1078 
1079     /**
1080      * Tests scenario where an UID had {@code restrict-background} and {@code uid-policy} tags.
1081      */
1082     @Test
1083     @NetPolicyXml("restrict-background-lists-mixed-format.xml")
testRestrictBackgroundLists_mixedFormat()1084     public void testRestrictBackgroundLists_mixedFormat() throws Exception {
1085         assertRestrictBackgroundAllowedUids(UID_A, UID_C, UID_D);
1086         assertUidPolicy(UID_A, POLICY_ALLOW_METERED_BACKGROUND);
1087         assertUidPolicy(UID_B, POLICY_REJECT_METERED_BACKGROUND); // Denylist prevails.
1088         assertUidPolicy(UID_C, (POLICY_ALLOW_METERED_BACKGROUND | 2));
1089         assertUidPolicy(UID_D, POLICY_ALLOW_METERED_BACKGROUND);
1090     }
1091 
1092     @Test
1093     @NetPolicyXml("uids-with-mixed-policies.xml")
testGetUidsWithPolicy()1094     public void testGetUidsWithPolicy() throws Exception {
1095         assertContainsInAnyOrder(mService.getUidsWithPolicy(POLICY_NONE));
1096         assertContainsInAnyOrder(mService.getUidsWithPolicy(POLICY_REJECT_METERED_BACKGROUND),
1097                 UID_B, UID_D);
1098         assertContainsInAnyOrder(mService.getUidsWithPolicy(POLICY_ALLOW_METERED_BACKGROUND),
1099                 UID_E, UID_F);
1100         // Legacy (POLICY_ALLOW_BACKGROUND_BATTERY_SAVE)
1101         assertContainsInAnyOrder(mService.getUidsWithPolicy(2),
1102                 UID_C, UID_D, UID_F);
1103     }
1104 
1105     // NOTE: testPolicyChangeTriggersListener() is too superficial, they
1106     // don't check for side-effects (like calls to NetworkManagementService) neither cover all
1107     // different modes (Data Saver, Battery Saver, Doze, App idle, etc...).
1108     // These scenarios are extensively tested on CTS' HostsideRestrictBackgroundNetworkTests.
1109     @SuppressWarnings("GuardedBy")
1110     @Test
testUidForeground()1111     public void testUidForeground() throws Exception {
1112         // push all uids into background
1113         long procStateSeq = 0;
1114         callAndWaitOnUidStateChanged(UID_A, PROCESS_STATE_SERVICE, procStateSeq++);
1115         callAndWaitOnUidStateChanged(UID_B, PROCESS_STATE_SERVICE, procStateSeq++);
1116         assertFalse(mService.isUidForegroundOnRestrictPowerUL(UID_A));
1117         assertFalse(mService.isUidForegroundOnRestrictBackgroundUL(UID_A));
1118         assertFalse(mService.isUidForegroundOnRestrictPowerUL(UID_B));
1119         assertFalse(mService.isUidForegroundOnRestrictBackgroundUL(UID_B));
1120 
1121         // push one of the uids into foreground
1122         callAndWaitOnUidStateChanged(UID_A, PROCESS_STATE_TOP, procStateSeq++);
1123         assertTrue(mService.isUidForegroundOnRestrictPowerUL(UID_A));
1124         assertTrue(mService.isUidForegroundOnRestrictBackgroundUL(UID_A));
1125         assertFalse(mService.isUidForegroundOnRestrictPowerUL(UID_B));
1126         assertFalse(mService.isUidForegroundOnRestrictBackgroundUL(UID_B));
1127 
1128         // and swap another uid into foreground
1129         callAndWaitOnUidStateChanged(UID_A, PROCESS_STATE_SERVICE, procStateSeq++);
1130         callAndWaitOnUidStateChanged(UID_B, PROCESS_STATE_TOP, procStateSeq++);
1131         assertFalse(mService.isUidForegroundOnRestrictPowerUL(UID_A));
1132         assertFalse(mService.isUidForegroundOnRestrictBackgroundUL(UID_A));
1133         assertTrue(mService.isUidForegroundOnRestrictPowerUL(UID_B));
1134         assertTrue(mService.isUidForegroundOnRestrictBackgroundUL(UID_B));
1135 
1136         // change capability of an uid to allow access to power restricted network
1137         callAndWaitOnUidStateChanged(UID_A, PROCESS_STATE_SERVICE, procStateSeq++,
1138                 PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK);
1139         callAndWaitOnUidStateChanged(UID_B, PROCESS_STATE_SERVICE, procStateSeq++,
1140                 PROCESS_CAPABILITY_NONE);
1141         assertTrue(mService.isUidForegroundOnRestrictPowerUL(UID_A));
1142         assertFalse(mService.isUidForegroundOnRestrictBackgroundUL(UID_A));
1143         assertFalse(mService.isUidForegroundOnRestrictPowerUL(UID_B));
1144         assertFalse(mService.isUidForegroundOnRestrictBackgroundUL(UID_B));
1145 
1146         // change capability of an uid to allow access to user restricted network
1147         callAndWaitOnUidStateChanged(UID_A, PROCESS_STATE_IMPORTANT_FOREGROUND, procStateSeq++,
1148                 PROCESS_CAPABILITY_USER_RESTRICTED_NETWORK);
1149         callAndWaitOnUidStateChanged(UID_B, PROCESS_STATE_SERVICE, procStateSeq++,
1150                 PROCESS_CAPABILITY_NONE);
1151         assertFalse(mService.isUidForegroundOnRestrictPowerUL(UID_A));
1152         assertTrue(mService.isUidForegroundOnRestrictBackgroundUL(UID_A));
1153         assertFalse(mService.isUidForegroundOnRestrictPowerUL(UID_B));
1154         assertFalse(mService.isUidForegroundOnRestrictBackgroundUL(UID_B));
1155     }
1156 
1157     @SuppressWarnings("GuardedBy")
1158     @Test
testUidForeground_withPendingState()1159     public void testUidForeground_withPendingState() throws Exception {
1160         long procStateSeq = 0;
1161         callAndWaitOnUidStateChanged(UID_A, PROCESS_STATE_SERVICE,
1162                 procStateSeq++, PROCESS_CAPABILITY_NONE);
1163         callAndWaitOnUidStateChanged(UID_B, PROCESS_STATE_SERVICE,
1164                 procStateSeq++, PROCESS_CAPABILITY_NONE);
1165         assertFalse(mService.isUidForegroundOnRestrictPowerUL(UID_A));
1166         assertFalse(mService.isUidForegroundOnRestrictBackgroundUL(UID_A));
1167         assertFalse(mService.isUidForegroundOnRestrictPowerUL(UID_B));
1168         assertFalse(mService.isUidForegroundOnRestrictBackgroundUL(UID_B));
1169 
1170         try (SyncBarrier b = new SyncBarrier(mService.mUidEventHandler)) {
1171             // Verify that a callback with an old procStateSeq is ignored.
1172             callOnUidStatechanged(UID_A, PROCESS_STATE_TOP, 0,
1173                     PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK);
1174             assertFalse(mService.isUidForegroundOnRestrictPowerUL(UID_A));
1175             assertFalse(mService.isUidForegroundOnRestrictBackgroundUL(UID_A));
1176             assertFalse(mService.isUidForegroundOnRestrictPowerUL(UID_B));
1177             assertFalse(mService.isUidForegroundOnRestrictBackgroundUL(UID_B));
1178 
1179             callOnUidStatechanged(UID_A, PROCESS_STATE_SERVICE, procStateSeq++,
1180                     PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK);
1181             assertTrue(mService.isUidForegroundOnRestrictPowerUL(UID_A));
1182             assertFalse(mService.isUidForegroundOnRestrictBackgroundUL(UID_A));
1183             assertFalse(mService.isUidForegroundOnRestrictPowerUL(UID_B));
1184             assertFalse(mService.isUidForegroundOnRestrictBackgroundUL(UID_B));
1185 
1186             callOnUidStatechanged(UID_A, PROCESS_STATE_IMPORTANT_FOREGROUND, procStateSeq++,
1187                     PROCESS_CAPABILITY_USER_RESTRICTED_NETWORK);
1188             assertFalse(mService.isUidForegroundOnRestrictPowerUL(UID_A));
1189             assertTrue(mService.isUidForegroundOnRestrictBackgroundUL(UID_A));
1190             assertFalse(mService.isUidForegroundOnRestrictPowerUL(UID_B));
1191             assertFalse(mService.isUidForegroundOnRestrictBackgroundUL(UID_B));
1192 
1193             callOnUidStatechanged(UID_A, PROCESS_STATE_TOP, procStateSeq++,
1194                     PROCESS_CAPABILITY_NONE);
1195             assertTrue(mService.isUidForegroundOnRestrictPowerUL(UID_A));
1196             assertTrue(mService.isUidForegroundOnRestrictBackgroundUL(UID_A));
1197             assertFalse(mService.isUidForegroundOnRestrictPowerUL(UID_B));
1198             assertFalse(mService.isUidForegroundOnRestrictBackgroundUL(UID_B));
1199         }
1200         waitForUidEventHandlerIdle();
1201 
1202         assertTrue(mService.isUidForegroundOnRestrictPowerUL(UID_A));
1203         assertTrue(mService.isUidForegroundOnRestrictBackgroundUL(UID_A));
1204         assertFalse(mService.isUidForegroundOnRestrictPowerUL(UID_B));
1205         assertFalse(mService.isUidForegroundOnRestrictBackgroundUL(UID_B));
1206 
1207         try (SyncBarrier b = new SyncBarrier(mService.mUidEventHandler)) {
1208             callOnUidStatechanged(UID_A, PROCESS_STATE_SERVICE, procStateSeq++,
1209                     PROCESS_CAPABILITY_NONE);
1210             assertTrue(mService.isUidForegroundOnRestrictPowerUL(UID_A));
1211             assertTrue(mService.isUidForegroundOnRestrictBackgroundUL(UID_A));
1212             assertFalse(mService.isUidForegroundOnRestrictPowerUL(UID_B));
1213             assertFalse(mService.isUidForegroundOnRestrictBackgroundUL(UID_B));
1214         }
1215         waitForUidEventHandlerIdle();
1216     }
1217 
1218     @Test
testAppIdleTempWhitelisting()1219     public void testAppIdleTempWhitelisting() throws Exception {
1220         mService.setAppIdleWhitelist(UID_A, true);
1221         mService.setAppIdleWhitelist(UID_B, false);
1222         int[] whitelistedIds = mService.getAppIdleWhitelist();
1223         assertTrue(Arrays.binarySearch(whitelistedIds, UID_A) >= 0);
1224         assertTrue(Arrays.binarySearch(whitelistedIds, UID_B) < 0);
1225         assertFalse(mService.isUidIdle(UID_A));
1226         // Can't currently guarantee UID_B's app idle state.
1227         // TODO: expand with multiple app idle states.
1228     }
1229 
1230     private static long computeLastCycleBoundary(long currentTime, NetworkPolicy policy) {
1231         RecurrenceRule.sClock = Clock.fixed(Instant.ofEpochMilli(currentTime),
1232                 ZoneId.systemDefault());
1233         final Iterator<Range<ZonedDateTime>> it = policy.cycleIterator();
1234         while (it.hasNext()) {
1235             final Range<ZonedDateTime> cycle = it.next();
1236             if (cycle.getLower().toInstant().toEpochMilli() < currentTime) {
1237                 return cycle.getLower().toInstant().toEpochMilli();
1238             }
1239         }
1240         throw new IllegalStateException(
1241                 "Failed to find current cycle for " + policy + " at " + currentTime);
1242     }
1243 
1244     private static long computeNextCycleBoundary(long currentTime, NetworkPolicy policy) {
1245         RecurrenceRule.sClock = Clock.fixed(Instant.ofEpochMilli(currentTime),
1246                 ZoneId.systemDefault());
1247         return policy.cycleIterator().next().getUpper().toInstant().toEpochMilli();
1248     }
1249 
1250     @Test
1251     public void testLastCycleBoundaryThisMonth() throws Exception {
1252         // assume cycle day of "5th", which should be in same month
1253         final long currentTime = parseTime("2007-11-14T00:00:00.000Z");
1254         final long expectedCycle = parseTime("2007-11-05T00:00:00.000Z");
1255 
1256         final NetworkPolicy policy = new NetworkPolicy(
1257                 sTemplateWifi, 5, TIMEZONE_UTC, 1024L, 1024L, false);
1258         final long actualCycle = computeLastCycleBoundary(currentTime, policy);
1259         assertTimeEquals(expectedCycle, actualCycle);
1260     }
1261 
1262     @Test
1263     public void testLastCycleBoundaryLastMonth() throws Exception {
1264         // assume cycle day of "20th", which should be in last month
1265         final long currentTime = parseTime("2007-11-14T00:00:00.000Z");
1266         final long expectedCycle = parseTime("2007-10-20T00:00:00.000Z");
1267 
1268         final NetworkPolicy policy = new NetworkPolicy(
1269                 sTemplateWifi, 20, TIMEZONE_UTC, 1024L, 1024L, false);
1270         final long actualCycle = computeLastCycleBoundary(currentTime, policy);
1271         assertTimeEquals(expectedCycle, actualCycle);
1272     }
1273 
1274     @Test
1275     public void testLastCycleBoundaryThisMonthFebruary() throws Exception {
1276         // assume cycle day of "30th" in february; should go to january
1277         final long currentTime = parseTime("2007-02-14T00:00:00.000Z");
1278         final long expectedCycle = parseTime("2007-01-30T00:00:00.000Z");
1279 
1280         final NetworkPolicy policy = new NetworkPolicy(
1281                 sTemplateWifi, 30, TIMEZONE_UTC, 1024L, 1024L, false);
1282         final long actualCycle = computeLastCycleBoundary(currentTime, policy);
1283         assertTimeEquals(expectedCycle, actualCycle);
1284     }
1285 
1286     @Test
1287     public void testLastCycleBoundaryLastMonthFebruary() throws Exception {
1288         // assume cycle day of "30th" in february, which should clamp
1289         final long currentTime = parseTime("2007-03-14T00:00:00.000Z");
1290         final long expectedCycle = parseTime("2007-02-28T23:59:59.999Z");
1291 
1292         final NetworkPolicy policy = new NetworkPolicy(
1293                 sTemplateWifi, 30, TIMEZONE_UTC, 1024L, 1024L, false);
1294         final long actualCycle = computeLastCycleBoundary(currentTime, policy);
1295         assertTimeEquals(expectedCycle, actualCycle);
1296     }
1297 
1298     @Test
1299     public void testCycleBoundaryLeapYear() throws Exception {
1300         final NetworkPolicy policy = new NetworkPolicy(
1301                 sTemplateWifi, 29, TIMEZONE_UTC, 1024L, 1024L, false);
1302 
1303         assertTimeEquals(parseTime("2012-01-29T00:00:00.000Z"),
1304                 computeNextCycleBoundary(parseTime("2012-01-14T00:00:00.000Z"), policy));
1305         assertTimeEquals(parseTime("2012-02-29T00:00:00.000Z"),
1306                 computeNextCycleBoundary(parseTime("2012-02-14T00:00:00.000Z"), policy));
1307         assertTimeEquals(parseTime("2012-02-29T00:00:00.000Z"),
1308                 computeLastCycleBoundary(parseTime("2012-03-14T00:00:00.000Z"), policy));
1309         assertTimeEquals(parseTime("2012-03-29T00:00:00.000Z"),
1310                 computeNextCycleBoundary(parseTime("2012-03-14T00:00:00.000Z"), policy));
1311 
1312         assertTimeEquals(parseTime("2007-01-29T00:00:00.000Z"),
1313                 computeNextCycleBoundary(parseTime("2007-01-14T00:00:00.000Z"), policy));
1314         assertTimeEquals(parseTime("2007-02-28T23:59:59.999Z"),
1315                 computeNextCycleBoundary(parseTime("2007-02-14T00:00:00.000Z"), policy));
1316         assertTimeEquals(parseTime("2007-02-28T23:59:59.999Z"),
1317                 computeLastCycleBoundary(parseTime("2007-03-14T00:00:00.000Z"), policy));
1318         assertTimeEquals(parseTime("2007-03-29T00:00:00.000Z"),
1319                 computeNextCycleBoundary(parseTime("2007-03-14T00:00:00.000Z"), policy));
1320     }
1321 
1322     @Test
1323     public void testNextCycleTimezoneAfterUtc() throws Exception {
1324         // US/Central is UTC-6
1325         final NetworkPolicy policy = new NetworkPolicy(
1326                 sTemplateWifi, 10, "US/Central", 1024L, 1024L, false);
1327         assertTimeEquals(parseTime("2012-01-10T06:00:00.000Z"),
1328                 computeNextCycleBoundary(parseTime("2012-01-05T00:00:00.000Z"), policy));
1329     }
1330 
1331     @Test
1332     public void testNextCycleTimezoneBeforeUtc() throws Exception {
1333         // Israel is UTC+2
1334         final NetworkPolicy policy = new NetworkPolicy(
1335                 sTemplateWifi, 10, "Israel", 1024L, 1024L, false);
1336         assertTimeEquals(parseTime("2012-01-09T22:00:00.000Z"),
1337                 computeNextCycleBoundary(parseTime("2012-01-05T00:00:00.000Z"), policy));
1338     }
1339 
1340     @Test
1341     public void testCycleTodayJanuary() throws Exception {
1342         final NetworkPolicy policy = new NetworkPolicy(
1343                 sTemplateWifi, 14, "US/Pacific", 1024L, 1024L, false);
1344 
1345         assertTimeEquals(parseTime("2013-01-14T00:00:00.000-08:00"),
1346                 computeNextCycleBoundary(parseTime("2013-01-13T23:59:59.000-08:00"), policy));
1347         assertTimeEquals(parseTime("2013-02-14T00:00:00.000-08:00"),
1348                 computeNextCycleBoundary(parseTime("2013-01-14T00:00:01.000-08:00"), policy));
1349         assertTimeEquals(parseTime("2013-02-14T00:00:00.000-08:00"),
1350                 computeNextCycleBoundary(parseTime("2013-01-14T15:11:00.000-08:00"), policy));
1351 
1352         assertTimeEquals(parseTime("2012-12-14T00:00:00.000-08:00"),
1353                 computeLastCycleBoundary(parseTime("2013-01-13T23:59:59.000-08:00"), policy));
1354         assertTimeEquals(parseTime("2013-01-14T00:00:00.000-08:00"),
1355                 computeLastCycleBoundary(parseTime("2013-01-14T00:00:01.000-08:00"), policy));
1356         assertTimeEquals(parseTime("2013-01-14T00:00:00.000-08:00"),
1357                 computeLastCycleBoundary(parseTime("2013-01-14T15:11:00.000-08:00"), policy));
1358     }
1359 
1360     @FlakyTest
1361     @Test
1362     public void testNetworkPolicyAppliedCycleLastMonth() throws Exception {
1363         List<NetworkStateSnapshot> snapshots = null;
1364         NetworkStats stats = null;
1365 
1366         final int CYCLE_DAY = 15;
1367         final long NOW = parseTime("2007-03-10T00:00Z");
1368         final long CYCLE_START = parseTime("2007-02-15T00:00Z");
1369         final long CYCLE_END = parseTime("2007-03-15T00:00Z");
1370 
1371         setCurrentTimeMillis(NOW);
1372 
1373         // first, pretend that wifi network comes online. no policy active,
1374         // which means we shouldn't push limit to interface.
1375         snapshots = List.of(buildWifi());
1376         when(mConnManager.getAllNetworkStateSnapshots()).thenReturn(snapshots);
1377 
1378         mPolicyListener.expect().onMeteredIfacesChanged(any());
1379         mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION));
1380         mPolicyListener.waitAndVerify().onMeteredIfacesChanged(any());
1381 
1382         // now change cycle to be on 15th, and test in early march, to verify we
1383         // pick cycle day in previous month.
1384         when(mConnManager.getAllNetworkStateSnapshots()).thenReturn(snapshots);
1385 
1386         // pretend that 512 bytes total have happened
1387         mDeps.setMockedTotalBytes(UID_A, 256L, 256L);
1388 
1389         mPolicyListener.expect().onMeteredIfacesChanged(any());
1390         setNetworkPolicies(new NetworkPolicy(
1391                 sTemplateWifi, CYCLE_DAY, TIMEZONE_UTC, DataUnit.MEBIBYTES.toBytes(1),
1392                 DataUnit.MEBIBYTES.toBytes(2), false));
1393         mPolicyListener.waitAndVerify().onMeteredIfacesChanged(eq(new String[]{TEST_IFACE}));
1394 
1395         verify(mNetworkManager, atLeastOnce()).setInterfaceQuota(TEST_IFACE,
1396                 DataUnit.MEBIBYTES.toBytes(2) - 512);
1397     }
1398 
1399     @Test
1400     public void testNotificationWarningLimitSnooze() throws Exception {
1401         // Get active mobile network in place
1402         expectMobileDefaults();
1403         mService.updateNetworks();
1404 
1405         // Define simple data plan
1406         final SubscriptionPlan plan = buildMonthlyDataPlan(
1407                 ZonedDateTime.parse("2015-11-01T00:00:00.00Z"), DataUnit.MEGABYTES.toBytes(1800));
1408         setSubscriptionPlans(TEST_SUB_ID, new SubscriptionPlan[] { plan },
1409                 mServiceContext.getOpPackageName());
1410 
1411         // We're 20% through the month (6 days)
1412         final long start = parseTime("2015-11-01T00:00Z");
1413         final long end = parseTime("2015-11-07T00:00Z");
1414         setCurrentTimeMillis(end);
1415 
1416         // Normal usage means no notification
1417         {
1418             mDeps.setMockedTotalBytes(UID_A, DataUnit.MEGABYTES.toBytes(360), 0);
1419 
1420             reset(mTelephonyManager, mNetworkManager, mNotifManager);
1421             TelephonyManager tmSub = expectMobileDefaults();
1422             clearInvocations(mNotifManager);
1423 
1424             mService.updateNetworks();
1425 
1426             verify(tmSub, atLeastOnce()).setPolicyDataEnabled(true);
1427             verify(mNetworkManager, atLeastOnce()).setInterfaceQuota(TEST_IFACE,
1428                     DataUnit.MEGABYTES.toBytes(1800 - 360));
1429             verify(mNotifManager, never()).notifyAsUser(any(), anyInt(), any(), any());
1430         }
1431 
1432         // Push over warning
1433         {
1434             mDeps.setMockedTotalBytes(UID_A, DataUnit.MEGABYTES.toBytes(1799), 0);
1435 
1436             reset(mTelephonyManager, mNetworkManager, mNotifManager);
1437             TelephonyManager tmSub = expectMobileDefaults();
1438             clearInvocations(mNotifManager);
1439 
1440             mService.updateNetworks();
1441 
1442             verify(tmSub, atLeastOnce()).setPolicyDataEnabled(true);
1443             verify(mNetworkManager, atLeastOnce()).setInterfaceQuota(TEST_IFACE,
1444                     DataUnit.MEGABYTES.toBytes(1800 - 1799));
1445             verify(mNotifManager, atLeastOnce()).notifyAsUser(any(), eq(TYPE_WARNING),
1446                     isA(Notification.class), eq(UserHandle.ALL));
1447         }
1448 
1449         // Push over warning, but with a config that isn't from an identified carrier
1450         {
1451             mDeps.setMockedTotalBytes(UID_A, DataUnit.MEGABYTES.toBytes(1799), 0);
1452 
1453             reset(mTelephonyManager, mNetworkManager, mNotifManager);
1454             TelephonyManager tmSub = expectMobileDefaults();
1455             expectDefaultCarrierConfig();
1456             clearInvocations(mNotifManager);
1457 
1458             mService.updateNetworks();
1459 
1460             verify(tmSub, atLeastOnce()).setPolicyDataEnabled(true);
1461             verify(mNetworkManager, atLeastOnce()).setInterfaceQuota(TEST_IFACE,
1462                     DataUnit.MEGABYTES.toBytes(1800 - 1799));
1463             // Since this isn't from the identified carrier, there should be no notifications
1464             verify(mNotifManager, never()).notifyAsUser(any(), anyInt(), any(), any());
1465         }
1466 
1467         // Push over limit
1468         {
1469             mDeps.setMockedTotalBytes(UID_A, DataUnit.MEGABYTES.toBytes(1810), 0);
1470 
1471             reset(mTelephonyManager, mNetworkManager, mNotifManager);
1472             TelephonyManager tmSub = expectMobileDefaults();
1473             clearInvocations(mNotifManager);
1474 
1475             mService.updateNetworks();
1476 
1477             verify(tmSub, atLeastOnce()).setPolicyDataEnabled(false);
1478             verify(mNetworkManager, atLeastOnce()).setInterfaceQuota(TEST_IFACE, 1);
1479             verify(mNotifManager, atLeastOnce()).notifyAsUser(any(), eq(TYPE_LIMIT),
1480                     isA(Notification.class), eq(UserHandle.ALL));
1481         }
1482 
1483         // Snooze limit
1484         {
1485             reset(mTelephonyManager, mNetworkManager, mNotifManager);
1486             TelephonyManager tmSub = expectMobileDefaults();
1487             clearInvocations(mNotifManager);
1488 
1489             mService.snoozeLimit(sTemplateCarrierMetered);
1490             mService.updateNetworks();
1491 
1492             verify(tmSub, atLeastOnce()).setPolicyDataEnabled(true);
1493             verify(mNetworkManager, atLeastOnce()).setInterfaceQuota(TEST_IFACE,
1494                     Long.MAX_VALUE);
1495             verify(mNotifManager, atLeastOnce()).notifyAsUser(any(), eq(TYPE_LIMIT_SNOOZED),
1496                     isA(Notification.class), eq(UserHandle.ALL));
1497         }
1498         // The sub is no longer used for data(e.g. user uses another sub), hide the notifications.
1499         {
1500             reset(mTelephonyManager, mNetworkManager, mNotifManager);
1501 
1502             notifyDefaultAndActiveDataSubIdChange(TEST_SUB_ID2, TEST_SUB_ID2);
1503             verify(mNotifManager, atLeastOnce()).cancel(any(), eq(TYPE_LIMIT_SNOOZED));
1504         }
1505         // The sub is not active for data(e.g. due to auto data switch), but still default for data,
1506         // show notification.
1507         {
1508             reset(mTelephonyManager, mNetworkManager, mNotifManager);
1509 
1510             notifyDefaultAndActiveDataSubIdChange(TEST_SUB_ID, TEST_SUB_ID2);
1511             verify(mNotifManager, atLeastOnce()).notifyAsUser(any(), eq(TYPE_LIMIT_SNOOZED),
1512                     isA(Notification.class), eq(UserHandle.ALL));
1513         }
1514         // The sub is active for data, but not the default(e.g. due to auto data switch),
1515         // show notification.
1516         {
1517             reset(mTelephonyManager, mNetworkManager, mNotifManager);
1518 
1519             notifyDefaultAndActiveDataSubIdChange(TEST_SUB_ID2, TEST_SUB_ID);
1520             verify(mNotifManager, atLeastOnce()).notifyAsUser(any(), eq(TYPE_LIMIT_SNOOZED),
1521                     isA(Notification.class), eq(UserHandle.ALL));
1522         }
1523     }
1524 
1525     @Test
1526     public void testNotificationRapid() throws Exception {
1527         // Get active mobile network in place
1528         expectMobileDefaults();
1529         mService.updateNetworks();
1530 
1531         // Define simple data plan which gives us effectively 60MB/day
1532         final SubscriptionPlan plan = buildMonthlyDataPlan(
1533                 ZonedDateTime.parse("2015-11-01T00:00:00.00Z"), DataUnit.MEGABYTES.toBytes(1800));
1534         setSubscriptionPlans(TEST_SUB_ID, new SubscriptionPlan[] { plan },
1535                 mServiceContext.getOpPackageName());
1536 
1537         // We're 20% through the month (6 days)
1538         final long start = parseTime("2015-11-01T00:00Z");
1539         final long end = parseTime("2015-11-07T00:00Z");
1540         setCurrentTimeMillis(end);
1541 
1542         // Using 20% data in 20% time is normal
1543         {
1544             mDeps.setMockedTotalBytes(UID_A, DataUnit.MEGABYTES.toBytes(360), 0);
1545 
1546             reset(mNotifManager);
1547             mService.updateNetworks();
1548             verify(mNotifManager, never()).notifyAsUser(any(), anyInt(), any(), any());
1549         }
1550 
1551         // Using 80% data in 20% time is alarming; but spread equally among
1552         // three UIDs means we get generic alert
1553         {
1554             mDeps.setMockedTotalBytes(UID_A, DataUnit.MEGABYTES.toBytes(480), 0);
1555             mDeps.setMockedTotalBytes(UID_B, DataUnit.MEGABYTES.toBytes(480), 0);
1556             mDeps.setMockedTotalBytes(UID_C, DataUnit.MEGABYTES.toBytes(480), 0);
1557 
1558             reset(mNotifManager);
1559             mService.updateNetworks();
1560 
1561             final ArgumentCaptor<Notification> notif = ArgumentCaptor.forClass(Notification.class);
1562             verify(mNotifManager, atLeastOnce()).notifyAsUser(any(), eq(TYPE_RAPID),
1563                     notif.capture(), eq(UserHandle.ALL));
1564 
1565             final String text = notif.getValue().extras.getCharSequence(Notification.EXTRA_TEXT)
1566                     .toString();
1567             assertFalse(text.contains(PKG_NAME_A));
1568             assertFalse(text.contains(PKG_NAME_B));
1569             assertFalse(text.contains(PKG_NAME_C));
1570         }
1571 
1572         // Using 80% data in 20% time is alarming; but mostly done by one UID
1573         // means we get specific alert
1574         {
1575             mDeps.setMockedTotalBytes(UID_A, DataUnit.MEGABYTES.toBytes(960), 0);
1576             mDeps.setMockedTotalBytes(UID_B, DataUnit.MEGABYTES.toBytes(480), 0);
1577             mDeps.setMockedTotalBytes(UID_C, 0, 0);
1578 
1579             reset(mNotifManager);
1580             mService.updateNetworks();
1581 
1582             final ArgumentCaptor<Notification> notif = ArgumentCaptor.forClass(Notification.class);
1583             verify(mNotifManager, atLeastOnce()).notifyAsUser(any(), eq(TYPE_RAPID),
1584                     notif.capture(), eq(UserHandle.ALL));
1585 
1586             final String text = notif.getValue().extras.getCharSequence(Notification.EXTRA_TEXT)
1587                     .toString();
1588             assertTrue(text.contains(PKG_NAME_A));
1589             assertFalse(text.contains(PKG_NAME_B));
1590             assertFalse(text.contains(PKG_NAME_C));
1591         }
1592     }
1593 
1594     @Test
1595     public void testMeteredNetworkWithoutLimit() throws Exception {
1596         List<NetworkStateSnapshot> snapshots = null;
1597         NetworkStats stats = null;
1598 
1599         final long TIME_FEB_15 = 1171497600000L;
1600         final long TIME_MAR_10 = 1173484800000L;
1601         final int CYCLE_DAY = 15;
1602 
1603         setCurrentTimeMillis(TIME_MAR_10);
1604 
1605         // bring up wifi network with metered policy
1606         snapshots = List.of(buildWifi());
1607         mDeps.setMockedTotalBytes(UID_A, 0L, 0L);
1608 
1609         {
1610             when(mConnManager.getAllNetworkStateSnapshots()).thenReturn(snapshots);
1611 
1612             mPolicyListener.expect().onMeteredIfacesChanged(any());
1613             setNetworkPolicies(new NetworkPolicy(
1614                     sTemplateWifi, CYCLE_DAY, TIMEZONE_UTC, WARNING_DISABLED, LIMIT_DISABLED,
1615                     true));
1616             mPolicyListener.waitAndVerify().onMeteredIfacesChanged(eq(new String[]{TEST_IFACE}));
1617 
1618             verify(mNetworkManager, atLeastOnce()).setInterfaceQuota(TEST_IFACE,
1619                     Long.MAX_VALUE);
1620         }
1621     }
1622 
1623     @Test
1624     public void testOnUidStateChanged_notifyAMS() throws Exception {
1625         final long procStateSeq = 222;
1626         callAndWaitOnUidStateChanged(UID_A, PROCESS_STATE_SERVICE, procStateSeq);
1627         verify(mActivityManagerInternal).notifyNetworkPolicyRulesUpdated(UID_A, procStateSeq);
1628     }
1629 
1630     private void callAndWaitOnUidGone(int uid) throws Exception {
1631         // The disabled argument is used only for ephemeral apps and does not matter here.
1632         mUidObserver.onUidGone(uid, false /* disabled */);
1633         waitForUidEventHandlerIdle();
1634     }
1635 
1636     private void callAndWaitOnUidStateChanged(int uid, int procState, long procStateSeq)
1637             throws Exception {
1638         callAndWaitOnUidStateChanged(uid, procState, procStateSeq,
1639                 PROCESS_CAPABILITY_NONE);
1640     }
1641 
1642     private void callAndWaitOnUidStateChanged(int uid, int procState, long procStateSeq,
1643             int capability) throws Exception {
1644         callOnUidStatechanged(uid, procState, procStateSeq, capability);
1645         waitForUidEventHandlerIdle();
1646     }
1647 
1648     private void callOnUidStatechanged(int uid, int procState, long procStateSeq, int capability)
1649             throws Exception {
1650         mUidObserver.onUidStateChanged(uid, procState, procStateSeq, capability);
1651     }
1652 
1653     private void waitForUidEventHandlerIdle() throws Exception {
1654         final CountDownLatch latch = new CountDownLatch(1);
1655         mService.mUidEventHandler.post(() -> {
1656             latch.countDown();
1657         });
1658         latch.await(2, TimeUnit.SECONDS);
1659     }
1660 
1661     private void assertCycleDayAsExpected(PersistableBundle config, int carrierCycleDay,
1662             boolean expectValid) {
1663         config.putInt(KEY_MONTHLY_DATA_CYCLE_DAY_INT, carrierCycleDay);
1664         int actualCycleDay = mService.getCycleDayFromCarrierConfig(config,
1665                 INVALID_CARRIER_CONFIG_VALUE);
1666         if (expectValid) {
1667             assertEquals(carrierCycleDay, actualCycleDay);
1668         } else {
1669             // INVALID_CARRIER_CONFIG_VALUE is returned for invalid values
1670             assertEquals(INVALID_CARRIER_CONFIG_VALUE, actualCycleDay);
1671         }
1672     }
1673 
1674     @Test
1675     public void testGetCycleDayFromCarrierConfig() {
1676         PersistableBundle config = CarrierConfigManager.getDefaultConfig();
1677         final Calendar cal = Calendar.getInstance();
1678         int actualCycleDay;
1679 
1680         config.putInt(KEY_MONTHLY_DATA_CYCLE_DAY_INT, DATA_CYCLE_USE_PLATFORM_DEFAULT);
1681         actualCycleDay = mService.getCycleDayFromCarrierConfig(config, DEFAULT_CYCLE_DAY);
1682         assertEquals(DEFAULT_CYCLE_DAY, actualCycleDay);
1683 
1684         // null config returns a default value
1685         actualCycleDay = mService.getCycleDayFromCarrierConfig(null, DEFAULT_CYCLE_DAY);
1686         assertEquals(DEFAULT_CYCLE_DAY, actualCycleDay);
1687 
1688         // Valid, non-default values
1689         assertCycleDayAsExpected(config, 1, true);
1690         assertCycleDayAsExpected(config, cal.getMaximum(Calendar.DAY_OF_MONTH), true);
1691         assertCycleDayAsExpected(config, cal.getMinimum(Calendar.DAY_OF_MONTH), true);
1692 
1693         // Invalid values
1694         assertCycleDayAsExpected(config, 0, false);
1695         assertCycleDayAsExpected(config, DATA_CYCLE_THRESHOLD_DISABLED, false);
1696         assertCycleDayAsExpected(config, cal.getMaximum(Calendar.DAY_OF_MONTH) + 1, false);
1697         assertCycleDayAsExpected(config, cal.getMinimum(Calendar.DAY_OF_MONTH) - 5, false);
1698     }
1699 
1700     private void assertWarningBytesAsExpected(PersistableBundle config, long carrierWarningBytes,
1701             long expected) {
1702         config.putLong(KEY_DATA_WARNING_THRESHOLD_BYTES_LONG, carrierWarningBytes);
1703         long actualWarning = mService.getWarningBytesFromCarrierConfig(config,
1704                 INVALID_CARRIER_CONFIG_VALUE);
1705         assertEquals(expected, actualWarning);
1706     }
1707 
1708     @Test
1709     public void testGetWarningBytesFromCarrierConfig() {
1710         PersistableBundle config = CarrierConfigManager.getDefaultConfig();
1711         long actualWarningBytes;
1712 
1713         assertWarningBytesAsExpected(config, DATA_CYCLE_USE_PLATFORM_DEFAULT,
1714                 mDefaultWarningBytes);
1715         assertWarningBytesAsExpected(config, DATA_CYCLE_THRESHOLD_DISABLED, WARNING_DISABLED);
1716         assertWarningBytesAsExpected(config, 0, 0);
1717         // not a valid value
1718         assertWarningBytesAsExpected(config, -1000, INVALID_CARRIER_CONFIG_VALUE);
1719 
1720         // null config returns a default value
1721         actualWarningBytes = mService.getWarningBytesFromCarrierConfig(null, mDefaultWarningBytes);
1722         assertEquals(mDefaultWarningBytes, actualWarningBytes);
1723     }
1724 
1725     private void assertLimitBytesAsExpected(PersistableBundle config,  long carrierWarningBytes,
1726             long expected) {
1727         config.putLong(KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG, carrierWarningBytes);
1728         long actualWarning = mService.getLimitBytesFromCarrierConfig(config,
1729                 INVALID_CARRIER_CONFIG_VALUE);
1730         assertEquals(expected, actualWarning);
1731     }
1732 
1733     @Test
1734     public void testGetLimitBytesFromCarrierConfig() {
1735         PersistableBundle config = CarrierConfigManager.getDefaultConfig();
1736         long actualLimitBytes;
1737 
1738         assertLimitBytesAsExpected(config, DATA_CYCLE_USE_PLATFORM_DEFAULT,
1739                 mDefaultLimitBytes);
1740         assertLimitBytesAsExpected(config, DATA_CYCLE_THRESHOLD_DISABLED, LIMIT_DISABLED);
1741         assertLimitBytesAsExpected(config, 0, 0);
1742         // not a valid value
1743         assertLimitBytesAsExpected(config, -1000, INVALID_CARRIER_CONFIG_VALUE);
1744 
1745         // null config returns a default value
1746         actualLimitBytes = mService.getWarningBytesFromCarrierConfig(null, mDefaultLimitBytes);
1747         assertEquals(mDefaultLimitBytes, actualLimitBytes);
1748     }
1749 
1750     private PersistableBundle setupUpdateCarrierPolicyCycleTests() throws RemoteException {
1751         when(mConnManager.getAllNetworkStateSnapshots())
1752                 .thenReturn(new ArrayList<NetworkStateSnapshot>());
1753 
1754         setupTelephonySubscriptionManagers(FAKE_SUB_ID, FAKE_SUBSCRIBER_ID);
1755 
1756         PersistableBundle bundle = CarrierConfigManager.getDefaultConfig();
1757         when(mCarrierConfigManager.getConfigForSubId(FAKE_SUB_ID)).thenReturn(bundle);
1758         setNetworkPolicies(buildDefaultFakeCarrierPolicy());
1759         return bundle;
1760     }
1761 
1762     @Test
1763     public void testUpdateCarrierPolicyCycleWithNullConfig() throws RemoteException {
1764         when(mConnManager.getAllNetworkStateSnapshots())
1765                 .thenReturn(new ArrayList<NetworkStateSnapshot>());
1766 
1767         setupTelephonySubscriptionManagers(FAKE_SUB_ID, FAKE_SUBSCRIBER_ID);
1768 
1769         when(mCarrierConfigManager.getConfigForSubId(FAKE_SUB_ID)).thenReturn(null);
1770         setNetworkPolicies(buildDefaultFakeCarrierPolicy());
1771         // smoke test to make sure no errors are raised
1772         mServiceContext.sendBroadcast(
1773                 new Intent(ACTION_CARRIER_CONFIG_CHANGED)
1774                         .putExtra(CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX, FAKE_SUB_ID)
1775         );
1776         assertNetworkPolicyEquals(DEFAULT_CYCLE_DAY, mDefaultWarningBytes, mDefaultLimitBytes,
1777                 true);
1778     }
1779 
1780     @Test
1781     public void testUpdateCarrierPolicyCycleWithInvalidConfig() throws RemoteException {
1782         PersistableBundle bundle = setupUpdateCarrierPolicyCycleTests();
1783         // Test with an invalid CarrierConfig, there should be no changes or crashes.
1784         bundle.putInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT, -100);
1785         bundle.putLong(CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG, -100);
1786         bundle.putLong(CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG, -100);
1787         mServiceContext.sendBroadcast(
1788                 new Intent(ACTION_CARRIER_CONFIG_CHANGED)
1789                         .putExtra(CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX, FAKE_SUB_ID)
1790         );
1791 
1792         assertNetworkPolicyEquals(DEFAULT_CYCLE_DAY, mDefaultWarningBytes, mDefaultLimitBytes,
1793                 true);
1794     }
1795 
1796     @Test
1797     public void testUpdateCarrierPolicyCycleWithDefaultConfig() throws RemoteException {
1798         PersistableBundle bundle = setupUpdateCarrierPolicyCycleTests();
1799         // Test that we respect the platform values when told to
1800         bundle.putInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT,
1801                 DATA_CYCLE_USE_PLATFORM_DEFAULT);
1802         bundle.putLong(CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG,
1803                 DATA_CYCLE_USE_PLATFORM_DEFAULT);
1804         bundle.putLong(CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG,
1805                 DATA_CYCLE_USE_PLATFORM_DEFAULT);
1806         mServiceContext.sendBroadcast(
1807                 new Intent(ACTION_CARRIER_CONFIG_CHANGED)
1808                         .putExtra(CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX, FAKE_SUB_ID)
1809         );
1810 
1811         assertNetworkPolicyEquals(DEFAULT_CYCLE_DAY, mDefaultWarningBytes, mDefaultLimitBytes,
1812                 true);
1813     }
1814 
1815     @Test
1816     public void testUpdateCarrierPolicyCycleWithUserOverrides() throws RemoteException {
1817         PersistableBundle bundle = setupUpdateCarrierPolicyCycleTests();
1818 
1819         // inferred = false implies that a user manually modified this policy.
1820         NetworkPolicy policy = buildDefaultFakeCarrierPolicy();
1821         policy.inferred = false;
1822         setNetworkPolicies(policy);
1823 
1824         bundle.putInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT, 31);
1825         bundle.putLong(CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG, 9999);
1826         bundle.putLong(CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG,
1827                 DATA_CYCLE_THRESHOLD_DISABLED);
1828         mServiceContext.sendBroadcast(
1829                 new Intent(ACTION_CARRIER_CONFIG_CHANGED)
1830                         .putExtra(CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX, FAKE_SUB_ID)
1831         );
1832 
1833         // The policy still shouldn't change, because we don't want to overwrite user settings.
1834         assertNetworkPolicyEquals(DEFAULT_CYCLE_DAY, mDefaultWarningBytes, mDefaultLimitBytes,
1835                 false);
1836     }
1837 
1838     @Test
1839     public void testUpdateCarrierPolicyCycleUpdatesDataCycle() throws RemoteException {
1840         PersistableBundle bundle = setupUpdateCarrierPolicyCycleTests();
1841 
1842         bundle.putInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT, 31);
1843         bundle.putLong(CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG, 9999);
1844         bundle.putLong(CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG, 9999);
1845         mServiceContext.sendBroadcast(
1846                 new Intent(ACTION_CARRIER_CONFIG_CHANGED)
1847                         .putExtra(CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX, FAKE_SUB_ID)
1848         );
1849 
1850         assertNetworkPolicyEquals(31, 9999, 9999, true);
1851     }
1852 
1853     @Test
1854     public void testUpdateCarrierPolicyCycleDisableThresholds() throws RemoteException {
1855         PersistableBundle bundle = setupUpdateCarrierPolicyCycleTests();
1856 
1857         bundle.putInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT, 31);
1858         bundle.putLong(CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG,
1859                 DATA_CYCLE_THRESHOLD_DISABLED);
1860         bundle.putLong(CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG,
1861                 DATA_CYCLE_THRESHOLD_DISABLED);
1862         mServiceContext.sendBroadcast(
1863                 new Intent(ACTION_CARRIER_CONFIG_CHANGED)
1864                         .putExtra(CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX, FAKE_SUB_ID)
1865         );
1866 
1867         assertNetworkPolicyEquals(31, WARNING_DISABLED, LIMIT_DISABLED, true);
1868     }
1869 
1870     @Test
1871     public void testUpdateCarrierPolicyCycleRevertsToDefault() throws RemoteException {
1872         PersistableBundle bundle = setupUpdateCarrierPolicyCycleTests();
1873 
1874         bundle.putInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT, 31);
1875         bundle.putLong(CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG,
1876                 DATA_CYCLE_THRESHOLD_DISABLED);
1877         bundle.putLong(CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG,
1878                 DATA_CYCLE_THRESHOLD_DISABLED);
1879         mServiceContext.sendBroadcast(
1880                 new Intent(ACTION_CARRIER_CONFIG_CHANGED)
1881                         .putExtra(CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX, FAKE_SUB_ID)
1882         );
1883         assertNetworkPolicyEquals(31, WARNING_DISABLED, LIMIT_DISABLED, true);
1884 
1885         // If the user switches carriers to one that doesn't use a CarrierConfig, we should revert
1886         // to the default data limit and warning. The cycle date doesn't need to revert as it's
1887         // arbitrary anyways.
1888         bundle.putInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT,
1889                 DATA_CYCLE_USE_PLATFORM_DEFAULT);
1890         bundle.putLong(CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG,
1891                 DATA_CYCLE_USE_PLATFORM_DEFAULT);
1892         bundle.putLong(CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG,
1893                 DATA_CYCLE_USE_PLATFORM_DEFAULT);
1894         mServiceContext.sendBroadcast(
1895                 new Intent(ACTION_CARRIER_CONFIG_CHANGED)
1896                         .putExtra(CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX, FAKE_SUB_ID)
1897         );
1898 
1899         assertNetworkPolicyEquals(31, mDefaultWarningBytes, mDefaultLimitBytes,
1900                 true);
1901     }
1902 
1903     @Test
1904     public void testOpportunisticQuota() throws Exception {
1905         final Network net = TEST_NETWORK;
1906         final NetworkPolicyManagerInternal internal = LocalServices
1907                 .getService(NetworkPolicyManagerInternal.class);
1908 
1909         // Get active mobile network in place
1910         expectMobileDefaults();
1911         mService.updateNetworks();
1912 
1913         // We're 20% through the month (6 days)
1914         final long start = parseTime("2015-11-01T00:00Z");
1915         final long end = parseTime("2015-11-07T00:00Z");
1916         setCurrentTimeMillis(end);
1917 
1918         // Get some data usage in place
1919         mDeps.setMockedTotalBytes(UID_A, DataUnit.MEGABYTES.toBytes(360), 0);
1920 
1921         // No data plan
1922         {
1923             reset(mTelephonyManager, mNetworkManager, mNotifManager);
1924             expectMobileDefaults();
1925 
1926             mService.updateNetworks();
1927 
1928             // No quotas
1929             assertEquals(OPPORTUNISTIC_QUOTA_UNKNOWN,
1930                     internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_JOBS));
1931             assertEquals(OPPORTUNISTIC_QUOTA_UNKNOWN,
1932                     internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_MULTIPATH));
1933         }
1934 
1935         // Limited data plan
1936         {
1937             final SubscriptionPlan plan = buildMonthlyDataPlan(
1938                     ZonedDateTime.parse("2015-11-01T00:00:00.00Z"),
1939                     DataUnit.MEGABYTES.toBytes(1800));
1940             setSubscriptionPlans(TEST_SUB_ID, new SubscriptionPlan[]{plan},
1941                     mServiceContext.getOpPackageName());
1942 
1943             reset(mTelephonyManager, mNetworkManager, mNotifManager);
1944             expectMobileDefaults();
1945 
1946             mService.updateNetworks();
1947 
1948             // We have 1440MB and 24 days left, which is 60MB/day; assuming 10%
1949             // for quota split equally between two types gives 3MB.
1950             assertEquals(DataUnit.MEGABYTES.toBytes(3),
1951                     internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_JOBS));
1952             assertEquals(DataUnit.MEGABYTES.toBytes(3),
1953                     internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_MULTIPATH));
1954         }
1955 
1956         // Limited data plan, over quota
1957         {
1958             final SubscriptionPlan plan = buildMonthlyDataPlan(
1959                     ZonedDateTime.parse("2015-11-01T00:00:00.00Z"),
1960                     DataUnit.MEGABYTES.toBytes(100));
1961             setSubscriptionPlans(TEST_SUB_ID, new SubscriptionPlan[]{plan},
1962                     mServiceContext.getOpPackageName());
1963 
1964             reset(mTelephonyManager, mNetworkManager, mNotifManager);
1965             expectMobileDefaults();
1966 
1967             mService.updateNetworks();
1968 
1969             assertEquals(0L, internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_JOBS));
1970             assertEquals(0L, internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_MULTIPATH));
1971         }
1972 
1973         // Roaming
1974         {
1975             final SubscriptionPlan plan = buildMonthlyDataPlan(
1976                     ZonedDateTime.parse("2015-11-01T00:00:00.00Z"), BYTES_UNLIMITED);
1977             setSubscriptionPlans(TEST_SUB_ID, new SubscriptionPlan[]{plan},
1978                     mServiceContext.getOpPackageName());
1979 
1980             reset(mTelephonyManager, mNetworkManager, mNotifManager);
1981             expectMobileDefaults();
1982             expectNetworkStateSnapshot(true /* roaming */);
1983 
1984             mService.updateNetworks();
1985 
1986             assertEquals(0L, internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_JOBS));
1987             assertEquals(0L, internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_MULTIPATH));
1988         }
1989 
1990         // Unlimited data plan
1991         {
1992             final SubscriptionPlan plan = buildMonthlyDataPlan(
1993                     ZonedDateTime.parse("2015-11-01T00:00:00.00Z"), BYTES_UNLIMITED);
1994             setSubscriptionPlans(TEST_SUB_ID, new SubscriptionPlan[]{plan},
1995                     mServiceContext.getOpPackageName());
1996 
1997             reset(mTelephonyManager, mNetworkManager, mNotifManager);
1998             expectMobileDefaults();
1999 
2000             mService.updateNetworks();
2001 
2002             // 20MB/day, split equally between two types gives 10MB.
2003             assertEquals(DataUnit.MEBIBYTES.toBytes(10),
2004                     internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_JOBS));
2005             assertEquals(DataUnit.MEBIBYTES.toBytes(10),
2006                     internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_MULTIPATH));
2007 
2008             // Capabilities change to roaming
2009             final ConnectivityManager.NetworkCallback callback = mNetworkCallbackCaptor.getValue();
2010             assertNotNull(callback);
2011             expectNetworkStateSnapshot(true /* roaming */);
2012             callback.onCapabilitiesChanged(
2013                     TEST_NETWORK, buildNetworkCapabilities(TEST_SUB_ID, true /* roaming */));
2014 
2015             assertEquals(0, internal.getSubscriptionOpportunisticQuota(
2016                     TEST_NETWORK, NetworkPolicyManagerInternal.QUOTA_TYPE_MULTIPATH));
2017         }
2018     }
2019 
2020     /**
2021      * Test that policy set of {null, NetworkPolicy, null} does not crash and restores the valid
2022      * NetworkPolicy.
2023      */
2024     @Test
2025     public void testSetNetworkPolicies_withNullPolicies_doesNotThrow() {
2026         NetworkPolicy[] policies = new NetworkPolicy[3];
2027         policies[1] = buildDefaultFakeCarrierPolicy();
2028         setNetworkPolicies(policies);
2029 
2030         assertNetworkPolicyEquals(DEFAULT_CYCLE_DAY, mDefaultWarningBytes, mDefaultLimitBytes,
2031                 true);
2032     }
2033 
2034     private void triggerOnStatsProviderWarningOrLimitReached() throws InterruptedException {
2035         mService.notifyStatsProviderWarningOrLimitReached();
2036         // Wait for processing of MSG_STATS_PROVIDER_WARNING_OR_LIMIT_REACHED.
2037         postMsgAndWaitForCompletion();
2038         verify(mStatsManager).forceUpdate();
2039         // Wait for processing of MSG_*_INTERFACE_QUOTAS.
2040         postMsgAndWaitForCompletion();
2041     }
2042 
2043     /**
2044      * Test that when StatsProvider triggers warning and limit reached, new quotas will be
2045      * calculated and re-armed.
2046      */
2047     @Test
2048     public void testStatsProviderWarningAndLimitReached() throws Exception {
2049         final int CYCLE_DAY = 15;
2050 
2051         mDeps.setMockedTotalBytes(UID_A, 2999, 2000);
2052 
2053         // Get active mobile network in place
2054         expectMobileDefaults();
2055         mService.updateNetworks();
2056         verify(mStatsManager).setStatsProviderWarningAndLimitAsync(TEST_IFACE, Long.MAX_VALUE,
2057                 Long.MAX_VALUE);
2058 
2059         // Set warning to 7KB and limit to 10KB.
2060         setNetworkPolicies(new NetworkPolicy(
2061                 sTemplateCarrierMetered, CYCLE_DAY, TIMEZONE_UTC, 7000L, 10000L,
2062                 true));
2063         postMsgAndWaitForCompletion();
2064 
2065         // Verifies that remaining quotas are set to providers.
2066         verify(mStatsManager).setStatsProviderWarningAndLimitAsync(TEST_IFACE, 2001L, 5001L);
2067         reset(mStatsManager);
2068 
2069         // Increase the usage and simulates that limit reached fires earlier by provider,
2070         // but actually the quota is not yet reached. Verifies that the limit reached leads to
2071         // a force update and new quotas should be set.
2072         mDeps.increaseMockedTotalBytes(UID_A, 1000, 999);
2073         triggerOnStatsProviderWarningOrLimitReached();
2074         verify(mStatsManager).setStatsProviderWarningAndLimitAsync(TEST_IFACE, 2L, 3002L);
2075         reset(mStatsManager);
2076 
2077         // Increase the usage and simulate warning reached, the new warning should be unlimited
2078         // since service will disable warning quota to stop lower layer from keep triggering
2079         // warning reached event.
2080         mDeps.increaseMockedTotalBytes(UID_A, 1000L, 1000);
2081         triggerOnStatsProviderWarningOrLimitReached();
2082         verify(mStatsManager).setStatsProviderWarningAndLimitAsync(
2083                 TEST_IFACE, Long.MAX_VALUE, 1002L);
2084         reset(mStatsManager);
2085 
2086         // Increase the usage that over the warning and limit, the new limit should set to 1 to
2087         // block the network traffic.
2088         mDeps.increaseMockedTotalBytes(UID_A, 1000L, 1000);
2089         triggerOnStatsProviderWarningOrLimitReached();
2090         verify(mStatsManager).setStatsProviderWarningAndLimitAsync(TEST_IFACE, Long.MAX_VALUE, 1L);
2091         reset(mStatsManager);
2092     }
2093 
2094     private void enableRestrictedMode(boolean enable) throws Exception {
2095         mService.mRestrictedNetworkingMode = enable;
2096         mService.updateRestrictedModeAllowlistUL();
2097         verify(mNetworkManager).setFirewallChainEnabled(FIREWALL_CHAIN_RESTRICTED,
2098                 enable);
2099     }
2100 
2101     @Test
2102     public void testUpdateRestrictedModeAllowlist() throws Exception {
2103         // initialization calls setFirewallChainEnabled, so we want to reset the invocations.
2104         clearInvocations(mNetworkManager);
2105         expectHasUseRestrictedNetworksPermission(UID_A, true);
2106         expectHasUseRestrictedNetworksPermission(UID_B, false);
2107 
2108         // Set low enough proc-states to ensure these uids are allowed in the background chain.
2109         // To maintain clean separation between separate firewall chains, the tests could
2110         // check for the specific blockedReasons in the uidBlockedState.
2111         callAndWaitOnUidStateChanged(UID_A, BACKGROUND_THRESHOLD_STATE - 1, 21);
2112         callAndWaitOnUidStateChanged(UID_B, BACKGROUND_THRESHOLD_STATE - 1, 21);
2113 
2114         Map<Integer, Integer> firewallUidRules = new ArrayMap<>();
2115         doAnswer(arg -> {
2116             int[] uids = arg.getArgument(1);
2117             int[] rules = arg.getArgument(2);
2118             assertTrue(uids.length == rules.length);
2119 
2120             for (int i = 0; i < uids.length; ++i) {
2121                 firewallUidRules.put(uids[i], rules[i]);
2122             }
2123             return null;
2124         }).when(mNetworkManager).setFirewallUidRules(eq(FIREWALL_CHAIN_RESTRICTED),
2125                 any(int[].class), any(int[].class));
2126 
2127         enableRestrictedMode(true);
2128         assertEquals(FIREWALL_RULE_ALLOW, firewallUidRules.get(UID_A).intValue());
2129         assertFalse(mService.isUidNetworkingBlocked(UID_A, false));
2130         assertTrue(mService.isUidNetworkingBlocked(UID_B, false));
2131 
2132         enableRestrictedMode(false);
2133         assertFalse(mService.isUidNetworkingBlocked(UID_A, false));
2134         assertFalse(mService.isUidNetworkingBlocked(UID_B, false));
2135     }
2136 
2137     @Test
testUpdateRestrictedModeForUid()2138     public void testUpdateRestrictedModeForUid() throws Exception {
2139         // initialization calls setFirewallChainEnabled, so we want to reset the invocations.
2140         clearInvocations(mNetworkManager);
2141         expectHasUseRestrictedNetworksPermission(UID_A, true);
2142         expectHasUseRestrictedNetworksPermission(UID_B, false);
2143         enableRestrictedMode(true);
2144 
2145         // UID_D and UID_E are not part of installed applications list, so it won't have any
2146         // firewall rules set yet
2147         expectHasUseRestrictedNetworksPermission(UID_D, false);
2148         mService.updateRestrictedModeForUidUL(UID_D);
2149         verify(mNetworkManager).setFirewallUidRule(FIREWALL_CHAIN_RESTRICTED, UID_D,
2150                 FIREWALL_RULE_DEFAULT);
2151         assertTrue(mService.isUidNetworkingBlocked(UID_D, false));
2152 
2153         expectHasUseRestrictedNetworksPermission(UID_E, true);
2154         mService.updateRestrictedModeForUidUL(UID_E);
2155         verify(mNetworkManager).setFirewallUidRule(FIREWALL_CHAIN_RESTRICTED, UID_E,
2156                 FIREWALL_RULE_ALLOW);
2157         assertFalse(mService.isUidNetworkingBlocked(UID_E, false));
2158     }
2159 
2160     @Test
testBackgroundChainEnabled()2161     public void testBackgroundChainEnabled() throws Exception {
2162         verify(mNetworkManager).setFirewallChainEnabled(FIREWALL_CHAIN_BACKGROUND, true);
2163     }
2164 
2165     @Test
2166     @RequiresFlagsDisabled(Flags.FLAG_USE_DIFFERENT_DELAYS_FOR_BACKGROUND_CHAIN)
testBackgroundChainOnProcStateChangeSameDelay()2167     public void testBackgroundChainOnProcStateChangeSameDelay() throws Exception {
2168         // initialization calls setFirewallChainEnabled, so we want to reset the invocations.
2169         clearInvocations(mNetworkManager);
2170 
2171         mService.mBackgroundRestrictionDelayMs = 500; // To avoid waiting too long in tests.
2172 
2173         // The app will be blocked when there is no prior proc-state.
2174         assertTrue(mService.isUidNetworkingBlocked(UID_A, false));
2175 
2176         int procStateSeq = 23;
2177         callAndWaitOnUidStateChanged(UID_A, BACKGROUND_THRESHOLD_STATE - 1, procStateSeq++);
2178 
2179         verify(mNetworkManager).setFirewallUidRule(FIREWALL_CHAIN_BACKGROUND, UID_A,
2180                 FIREWALL_RULE_ALLOW);
2181         assertFalse(mService.isUidNetworkingBlocked(UID_A, false));
2182 
2183         callAndWaitOnUidStateChanged(UID_A, BACKGROUND_THRESHOLD_STATE + 1, procStateSeq++);
2184 
2185         // The app should be blocked after a delay. Posting a message just after the delay and
2186         // waiting for it to complete to ensure that the blocking code has executed.
2187         waitForDelayedMessageOnHandler(mService.mBackgroundRestrictionDelayMs + 1);
2188 
2189         verify(mNetworkManager).setFirewallUidRule(FIREWALL_CHAIN_BACKGROUND, UID_A,
2190                 FIREWALL_RULE_DEFAULT);
2191         assertTrue(mService.isUidNetworkingBlocked(UID_A, false));
2192     }
2193 
2194     @Test
2195     @RequiresFlagsEnabled(Flags.FLAG_USE_DIFFERENT_DELAYS_FOR_BACKGROUND_CHAIN)
testBackgroundChainOnProcStateChangeDifferentDelays()2196     public void testBackgroundChainOnProcStateChangeDifferentDelays() throws Exception {
2197         // The app will be blocked when there is no prior proc-state.
2198         assertTrue(mService.isUidNetworkingBlocked(UID_A, false));
2199 
2200         // Tweak delays to avoid waiting too long in tests.
2201         mService.mBackgroundRestrictionShortDelayMs = 50;
2202         mService.mBackgroundRestrictionLongDelayMs = 1000;
2203 
2204         int procStateSeq = 231; // Any arbitrary starting sequence.
2205         for (int ps = BACKGROUND_THRESHOLD_STATE; ps <= MAX_PROCESS_STATE; ps++) {
2206             clearInvocations(mNetworkManager);
2207 
2208             // Make sure app is in correct process-state to access network.
2209             callAndWaitOnUidStateChanged(UID_A, BACKGROUND_THRESHOLD_STATE - 1, procStateSeq++);
2210             verify(mNetworkManager).setFirewallUidRule(FIREWALL_CHAIN_BACKGROUND, UID_A,
2211                     FIREWALL_RULE_ALLOW);
2212             assertFalse(mService.isUidNetworkingBlocked(UID_A, false));
2213 
2214             // Now put the app into the background and test that it eventually loses network.
2215             callAndWaitOnUidStateChanged(UID_A, ps, procStateSeq++);
2216 
2217             final long uidStateChangeTime = SystemClock.uptimeMillis();
2218             if (ps <= PROCESS_STATE_LAST_ACTIVITY) {
2219                 // Verify that the app is blocked after long delay but not after short delay.
2220                 waitForDelayedMessageOnHandler(mService.mBackgroundRestrictionShortDelayMs + 1);
2221                 verify(mNetworkManager, never()).setFirewallUidRule(FIREWALL_CHAIN_BACKGROUND,
2222                         UID_A, FIREWALL_RULE_DEFAULT);
2223                 assertFalse(mService.isUidNetworkingBlocked(UID_A, false));
2224 
2225                 final long timeUntilLongDelay = uidStateChangeTime
2226                         + mService.mBackgroundRestrictionLongDelayMs - SystemClock.uptimeMillis();
2227                 assertTrue("No time left to verify long delay in background transition",
2228                         timeUntilLongDelay >= 0);
2229 
2230                 waitForDelayedMessageOnHandler(timeUntilLongDelay + 1);
2231                 verify(mNetworkManager).setFirewallUidRule(FIREWALL_CHAIN_BACKGROUND, UID_A,
2232                         FIREWALL_RULE_DEFAULT);
2233                 assertTrue(mService.isUidNetworkingBlocked(UID_A, false));
2234             } else {
2235                 // Verify that the app is blocked after short delay.
2236                 waitForDelayedMessageOnHandler(mService.mBackgroundRestrictionShortDelayMs + 1);
2237                 verify(mNetworkManager).setFirewallUidRule(FIREWALL_CHAIN_BACKGROUND, UID_A,
2238                         FIREWALL_RULE_DEFAULT);
2239                 assertTrue(mService.isUidNetworkingBlocked(UID_A, false));
2240             }
2241         }
2242     }
2243 
2244     @Test
testBackgroundChainOnAllowlistChange()2245     public void testBackgroundChainOnAllowlistChange() throws Exception {
2246         // initialization calls setFirewallChainEnabled, so we want to reset the invocations.
2247         clearInvocations(mNetworkManager);
2248 
2249         // The apps will be blocked when there is no prior proc-state.
2250         assertTrue(mService.isUidNetworkingBlocked(UID_A, false));
2251         assertTrue(mService.isUidNetworkingBlocked(UID_B, false));
2252 
2253         final int procStateSeq = 29;
2254         callAndWaitOnUidStateChanged(UID_A, BACKGROUND_THRESHOLD_STATE + 1, procStateSeq);
2255         assertTrue(mService.isUidNetworkingBlocked(UID_A, false));
2256 
2257         when(mPowerExemptionManager.getAllowListedAppIds(anyBoolean()))
2258                 .thenReturn(new int[]{APP_ID_A, APP_ID_B});
2259         final SparseIntArray firewallUidRules = new SparseIntArray();
2260         doAnswer(arg -> {
2261             final int[] uids = arg.getArgument(1);
2262             final int[] rules = arg.getArgument(2);
2263             assertTrue(uids.length == rules.length);
2264 
2265             for (int i = 0; i < uids.length; ++i) {
2266                 firewallUidRules.put(uids[i], rules[i]);
2267             }
2268             return null;
2269         }).when(mNetworkManager).setFirewallUidRules(eq(FIREWALL_CHAIN_BACKGROUND),
2270                 any(int[].class), any(int[].class));
2271 
2272         mPowerAllowlistReceiver.onReceive(mServiceContext, null);
2273 
2274         assertEquals(FIREWALL_RULE_ALLOW, firewallUidRules.get(UID_A, -1));
2275         assertEquals(FIREWALL_RULE_ALLOW, firewallUidRules.get(UID_B, -1));
2276 
2277         assertFalse(mService.isUidNetworkingBlocked(UID_A, false));
2278         assertFalse(mService.isUidNetworkingBlocked(UID_B, false));
2279     }
2280 
2281     @Test
testBackgroundChainOnTempAllowlistChange()2282     public void testBackgroundChainOnTempAllowlistChange() throws Exception {
2283         // initialization calls setFirewallChainEnabled, so we want to reset the invocations.
2284         clearInvocations(mNetworkManager);
2285 
2286         // The app will be blocked as is no prior proc-state.
2287         assertTrue(mService.isUidNetworkingBlocked(UID_A, false));
2288 
2289         final int procStateSeq = 19;
2290         callAndWaitOnUidStateChanged(UID_A, BACKGROUND_THRESHOLD_STATE + 1, procStateSeq);
2291         assertTrue(mService.isUidNetworkingBlocked(UID_A, false));
2292 
2293         final NetworkPolicyManagerInternal internal = LocalServices.getService(
2294                 NetworkPolicyManagerInternal.class);
2295 
2296         internal.onTempPowerSaveWhitelistChange(APP_ID_A, true, REASON_OTHER, "testing");
2297 
2298         verify(mNetworkManager).setFirewallUidRule(FIREWALL_CHAIN_BACKGROUND, UID_A,
2299                 FIREWALL_RULE_ALLOW);
2300         assertFalse(mService.isUidNetworkingBlocked(UID_A, false));
2301 
2302         internal.onTempPowerSaveWhitelistChange(APP_ID_A, false, REASON_OTHER, "testing");
2303 
2304         verify(mNetworkManager).setFirewallUidRule(FIREWALL_CHAIN_BACKGROUND, UID_A,
2305                 FIREWALL_RULE_DEFAULT);
2306         assertTrue(mService.isUidNetworkingBlocked(UID_A, false));
2307     }
2308 
2309     @SuppressWarnings("GuardedBy") // For not holding mUidRulesFirstLock
2310     @Test
2311     @RequiresFlagsEnabled(Flags.FLAG_NEVER_APPLY_RULES_TO_CORE_UIDS)
testRulesNeverAppliedToCoreUids()2312     public void testRulesNeverAppliedToCoreUids() throws Exception {
2313         clearInvocations(mNetworkManager);
2314 
2315         final int coreAppId = Process.FIRST_APPLICATION_UID - 102;
2316         final int coreUid = UserHandle.getUid(USER_ID, coreAppId);
2317 
2318         // Enable all restrictions and add this core uid to all allowlists.
2319         mService.mDeviceIdleMode = true;
2320         mService.mRestrictPower = true;
2321         setRestrictBackground(true);
2322         expectHasUseRestrictedNetworksPermission(coreUid, true);
2323         enableRestrictedMode(true);
2324         final NetworkPolicyManagerInternal internal = LocalServices.getService(
2325                 NetworkPolicyManagerInternal.class);
2326         internal.setLowPowerStandbyActive(true);
2327         internal.setLowPowerStandbyAllowlist(new int[]{coreUid});
2328         internal.onTempPowerSaveWhitelistChange(coreAppId, true, REASON_OTHER, "testing");
2329 
2330         when(mPowerExemptionManager.getAllowListedAppIds(anyBoolean()))
2331                 .thenReturn(new int[]{coreAppId});
2332         mPowerAllowlistReceiver.onReceive(mServiceContext, null);
2333 
2334         // A normal uid would undergo a rule change from denied to allowed on all chains, but we
2335         // should not request any rule change for this core uid.
2336         verify(mNetworkManager, never()).setFirewallUidRule(anyInt(), eq(coreUid), anyInt());
2337         verify(mNetworkManager, never()).setFirewallUidRules(anyInt(),
2338                 argThat(ar -> ArrayUtils.contains(ar, coreUid)), any(int[].class));
2339     }
2340 
2341     @SuppressWarnings("GuardedBy") // For not holding mUidRulesFirstLock
2342     @Test
2343     @RequiresFlagsEnabled(Flags.FLAG_NEVER_APPLY_RULES_TO_CORE_UIDS)
testRulesNeverAppliedToUidsWithoutInternetPermission()2344     public void testRulesNeverAppliedToUidsWithoutInternetPermission() throws Exception {
2345         clearInvocations(mNetworkManager);
2346 
2347         mService.mInternetPermissionMap.clear();
2348         expectHasInternetPermission(UID_A, false);
2349 
2350         // Enable all restrictions and add this uid to all allowlists.
2351         mService.mDeviceIdleMode = true;
2352         mService.mRestrictPower = true;
2353         setRestrictBackground(true);
2354         expectHasUseRestrictedNetworksPermission(UID_A, true);
2355         enableRestrictedMode(true);
2356         final NetworkPolicyManagerInternal internal = LocalServices.getService(
2357                 NetworkPolicyManagerInternal.class);
2358         internal.setLowPowerStandbyActive(true);
2359         internal.setLowPowerStandbyAllowlist(new int[]{UID_A});
2360         internal.onTempPowerSaveWhitelistChange(APP_ID_A, true, REASON_OTHER, "testing");
2361 
2362         when(mPowerExemptionManager.getAllowListedAppIds(anyBoolean()))
2363                 .thenReturn(new int[]{APP_ID_A});
2364         mPowerAllowlistReceiver.onReceive(mServiceContext, null);
2365 
2366         // A normal uid would undergo a rule change from denied to allowed on all chains, but we
2367         // should not request any rule this uid without the INTERNET permission.
2368         verify(mNetworkManager, never()).setFirewallUidRule(anyInt(), eq(UID_A), anyInt());
2369         verify(mNetworkManager, never()).setFirewallUidRules(anyInt(),
2370                 argThat(ar -> ArrayUtils.contains(ar, UID_A)), any(int[].class));
2371     }
2372 
isUidState(int uid, int procState, int procStateSeq, int capability)2373     private boolean isUidState(int uid, int procState, int procStateSeq, int capability) {
2374         final NetworkPolicyManager.UidState uidState = mService.getUidStateForTest(uid);
2375         if (uidState == null) {
2376             return false;
2377         }
2378         return uidState.uid == uid && uidState.procStateSeq == procStateSeq
2379                 && uidState.procState == procState && uidState.capability == capability;
2380     }
2381 
2382     @Test
testUidObserverFiltersProcStateChanges()2383     public void testUidObserverFiltersProcStateChanges() throws Exception {
2384         int testProcStateSeq = 0;
2385         try (SyncBarrier b = new SyncBarrier(mService.mUidEventHandler)) {
2386             // First callback for uid.
2387             callOnUidStatechanged(UID_A, BACKGROUND_THRESHOLD_STATE + 1, testProcStateSeq++,
2388                     PROCESS_CAPABILITY_NONE);
2389             assertTrue(mService.mUidEventHandler.hasMessages(UID_MSG_STATE_CHANGED));
2390         }
2391         waitForUidEventHandlerIdle();
2392         try (SyncBarrier b = new SyncBarrier(mService.mUidEventHandler)) {
2393             // Doesn't cross the background threshold.
2394             callOnUidStatechanged(UID_A, BACKGROUND_THRESHOLD_STATE, testProcStateSeq++,
2395                     PROCESS_CAPABILITY_NONE);
2396             assertFalse(mService.mUidEventHandler.hasMessages(UID_MSG_STATE_CHANGED));
2397         }
2398         waitForUidEventHandlerIdle();
2399         try (SyncBarrier b = new SyncBarrier(mService.mUidEventHandler)) {
2400             // Crosses the background threshold.
2401             callOnUidStatechanged(UID_A, BACKGROUND_THRESHOLD_STATE - 1, testProcStateSeq++,
2402                     PROCESS_CAPABILITY_NONE);
2403             assertTrue(mService.mUidEventHandler.hasMessages(UID_MSG_STATE_CHANGED));
2404         }
2405         waitForUidEventHandlerIdle();
2406         try (SyncBarrier b = new SyncBarrier(mService.mUidEventHandler)) {
2407             // Doesn't cross the foreground threshold.
2408             callOnUidStatechanged(UID_A, FOREGROUND_THRESHOLD_STATE + 1, testProcStateSeq++,
2409                     PROCESS_CAPABILITY_NONE);
2410             assertFalse(mService.mUidEventHandler.hasMessages(UID_MSG_STATE_CHANGED));
2411         }
2412         waitForUidEventHandlerIdle();
2413         try (SyncBarrier b = new SyncBarrier(mService.mUidEventHandler)) {
2414             // Crosses the foreground threshold.
2415             callOnUidStatechanged(UID_A, FOREGROUND_THRESHOLD_STATE, testProcStateSeq++,
2416                     PROCESS_CAPABILITY_NONE);
2417             assertTrue(mService.mUidEventHandler.hasMessages(UID_MSG_STATE_CHANGED));
2418         }
2419         waitForUidEventHandlerIdle();
2420         try (SyncBarrier b = new SyncBarrier(mService.mUidEventHandler)) {
2421             // Doesn't cross the top threshold.
2422             callOnUidStatechanged(UID_A, TOP_THRESHOLD_STATE + 1, testProcStateSeq++,
2423                     PROCESS_CAPABILITY_NONE);
2424             assertFalse(mService.mUidEventHandler.hasMessages(UID_MSG_STATE_CHANGED));
2425         }
2426         waitForUidEventHandlerIdle();
2427         try (SyncBarrier b = new SyncBarrier(mService.mUidEventHandler)) {
2428             // Crosses the top threshold.
2429             callOnUidStatechanged(UID_A, TOP_THRESHOLD_STATE, testProcStateSeq++,
2430                     PROCESS_CAPABILITY_NONE);
2431             assertTrue(mService.mUidEventHandler.hasMessages(UID_MSG_STATE_CHANGED));
2432         }
2433         waitForUidEventHandlerIdle();
2434         try (SyncBarrier b = new SyncBarrier(mService.mUidEventHandler)) {
2435             // Doesn't cross any threshold, but changes below TOP_THRESHOLD_STATE should always
2436             // be processed
2437             callOnUidStatechanged(UID_A, TOP_THRESHOLD_STATE - 1, testProcStateSeq++,
2438                     PROCESS_CAPABILITY_NONE);
2439             assertTrue(mService.mUidEventHandler.hasMessages(UID_MSG_STATE_CHANGED));
2440         }
2441         waitForUidEventHandlerIdle();
2442     }
2443 
2444     @Test
testUidObserverFiltersStaleChanges()2445     public void testUidObserverFiltersStaleChanges() throws Exception {
2446         final int testProcStateSeq = 51;
2447         try (SyncBarrier b = new SyncBarrier(mService.mUidEventHandler)) {
2448             // First callback for uid.
2449             callOnUidStatechanged(UID_B, BACKGROUND_THRESHOLD_STATE + 100, testProcStateSeq,
2450                     PROCESS_CAPABILITY_NONE);
2451             assertTrue(mService.mUidEventHandler.hasMessages(UID_MSG_STATE_CHANGED));
2452         }
2453         waitForUidEventHandlerIdle();
2454         try (SyncBarrier b = new SyncBarrier(mService.mUidEventHandler)) {
2455             // Stale callback because the procStateSeq is smaller.
2456             callOnUidStatechanged(UID_B, BACKGROUND_THRESHOLD_STATE - 100, testProcStateSeq - 10,
2457                     PROCESS_CAPABILITY_NONE);
2458             assertFalse(mService.mUidEventHandler.hasMessages(UID_MSG_STATE_CHANGED));
2459         }
2460         waitForUidEventHandlerIdle();
2461     }
2462 
2463     @Test
testUidObserverFiltersCapabilityChanges()2464     public void testUidObserverFiltersCapabilityChanges() throws Exception {
2465         int testProcStateSeq = 0;
2466         try (SyncBarrier b = new SyncBarrier(mService.mUidEventHandler)) {
2467             // First callback for uid.
2468             callOnUidStatechanged(UID_A, FOREGROUND_THRESHOLD_STATE, testProcStateSeq++,
2469                     PROCESS_CAPABILITY_NONE);
2470             assertTrue(mService.mUidEventHandler.hasMessages(UID_MSG_STATE_CHANGED));
2471         }
2472         waitForUidEventHandlerIdle();
2473         try (SyncBarrier b = new SyncBarrier(mService.mUidEventHandler)) {
2474             // The same process-state with one network capability added.
2475             callOnUidStatechanged(UID_A, FOREGROUND_THRESHOLD_STATE, testProcStateSeq++,
2476                     PROCESS_CAPABILITY_USER_RESTRICTED_NETWORK);
2477             assertTrue(mService.mUidEventHandler.hasMessages(UID_MSG_STATE_CHANGED));
2478         }
2479         waitForUidEventHandlerIdle();
2480         try (SyncBarrier b = new SyncBarrier(mService.mUidEventHandler)) {
2481             // The same process-state with another network capability added.
2482             callOnUidStatechanged(UID_A, FOREGROUND_THRESHOLD_STATE, testProcStateSeq++,
2483                     PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK
2484                             | PROCESS_CAPABILITY_USER_RESTRICTED_NETWORK);
2485             assertTrue(mService.mUidEventHandler.hasMessages(UID_MSG_STATE_CHANGED));
2486         }
2487         waitForUidEventHandlerIdle();
2488         try (SyncBarrier b = new SyncBarrier(mService.mUidEventHandler)) {
2489             // The same process-state with all capabilities, but no change in network capabilities.
2490             callOnUidStatechanged(UID_A, FOREGROUND_THRESHOLD_STATE, testProcStateSeq++,
2491                     PROCESS_CAPABILITY_ALL);
2492             assertFalse(mService.mUidEventHandler.hasMessages(UID_MSG_STATE_CHANGED));
2493         }
2494         waitForUidEventHandlerIdle();
2495 
2496         callAndWaitOnUidStateChanged(UID_A, TOP_THRESHOLD_STATE, testProcStateSeq++,
2497                 PROCESS_CAPABILITY_ALL);
2498         try (SyncBarrier b = new SyncBarrier(mService.mUidEventHandler)) {
2499             // No change in capabilities, but TOP_THRESHOLD_STATE change should always be processed.
2500             callOnUidStatechanged(UID_A, TOP_THRESHOLD_STATE, testProcStateSeq++,
2501                     PROCESS_CAPABILITY_ALL);
2502             assertTrue(mService.mUidEventHandler.hasMessages(UID_MSG_STATE_CHANGED));
2503         }
2504         waitForUidEventHandlerIdle();
2505     }
2506 
2507     @Test
testUidStateChangeAfterUidGone()2508     public void testUidStateChangeAfterUidGone() throws Exception {
2509         final int testProcStateSeq = 51;
2510         final int testProcState = PROCESS_STATE_IMPORTANT_FOREGROUND;
2511 
2512         try (SyncBarrier b = new SyncBarrier(mService.mUidEventHandler)) {
2513             // First callback for uid.
2514             callOnUidStatechanged(UID_B, testProcState, testProcStateSeq, PROCESS_CAPABILITY_NONE);
2515             assertTrue(mService.mUidEventHandler.hasMessages(UID_MSG_STATE_CHANGED));
2516         }
2517         waitForUidEventHandlerIdle();
2518         assertTrue(isUidState(UID_B, testProcState, testProcStateSeq, PROCESS_CAPABILITY_NONE));
2519 
2520         callAndWaitOnUidGone(UID_B);
2521         try (SyncBarrier b = new SyncBarrier(mService.mUidEventHandler)) {
2522             // Even though the procState is the same, the uid had exited - so this should be
2523             // processed as a fresh callback.
2524             callOnUidStatechanged(UID_B, testProcState, testProcStateSeq + 1,
2525                     PROCESS_CAPABILITY_NONE);
2526             assertTrue(mService.mUidEventHandler.hasMessages(UID_MSG_STATE_CHANGED));
2527         }
2528         waitForUidEventHandlerIdle();
2529         assertTrue(isUidState(UID_B, testProcState, testProcStateSeq + 1, PROCESS_CAPABILITY_NONE));
2530     }
2531 
2532     @Test
testObsoleteHandleUidGone()2533     public void testObsoleteHandleUidGone() throws Exception {
2534         callAndWaitOnUidStateChanged(UID_A, PROCESS_STATE_TOP, 51);
2535         assertFalse(mService.isUidNetworkingBlocked(UID_A, false));
2536 
2537         clearInvocations(mNetworkManager);
2538 
2539         // In the service, handleUidGone is only called from mUidEventHandler. Then a call to it may
2540         // be rendered obsolete by a newer uid change posted on the handler. The latest uid state
2541         // change is always reflected in the current UidStateChangeCallbackInfo for the uid, so to
2542         // simulate an obsolete call for test, we directly call handleUidGone and leave the state in
2543         // UidStateChangeCallbackInfo set by the previous call to onUidStateChanged(TOP). This call
2544         // should then do nothing.
2545         mService.handleUidGone(UID_A);
2546 
2547         verify(mNetworkManager, times(0)).setFirewallUidRule(anyInt(), anyInt(), anyInt());
2548         assertFalse(mService.isUidNetworkingBlocked(UID_A, false));
2549     }
2550 
2551     @Test
testObsoleteHandleUidChanged()2552     public void testObsoleteHandleUidChanged() throws Exception {
2553         callAndWaitOnUidGone(UID_A);
2554         assertTrue(mService.isUidNetworkingBlocked(UID_A, false));
2555 
2556         clearInvocations(mNetworkManager);
2557 
2558         // In the service, handleUidChanged is only called from mUidEventHandler. Then a call to it
2559         // may be rendered obsolete by an immediate uid-gone posted on the handler. The latest uid
2560         // state change is always reflected in the current UidStateChangeCallbackInfo for the uid,
2561         // so to simulate an obsolete call for test, we directly call handleUidChanged and leave the
2562         // state in UidStateChangeCallbackInfo as null as it would get removed by the previous call
2563         // to onUidGone(). This call should then do nothing.
2564         mService.handleUidChanged(UID_A);
2565 
2566         verify(mNetworkManager, times(0)).setFirewallUidRule(anyInt(), anyInt(), anyInt());
2567         assertTrue(mService.isUidNetworkingBlocked(UID_A, false));
2568     }
2569 
2570     @Test
testLowPowerStandbyAllowlist()2571     public void testLowPowerStandbyAllowlist() throws Exception {
2572         // Chain background is also enabled but these procstates are important enough to be exempt.
2573         callAndWaitOnUidStateChanged(UID_A, PROCESS_STATE_TOP, 0);
2574         callAndWaitOnUidStateChanged(UID_B, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 0);
2575         callAndWaitOnUidStateChanged(UID_C, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 0);
2576         expectHasInternetPermission(UID_A, true);
2577         expectHasInternetPermission(UID_B, true);
2578         expectHasInternetPermission(UID_C, true);
2579 
2580         final NetworkPolicyManagerInternal internal = LocalServices
2581                 .getService(NetworkPolicyManagerInternal.class);
2582 
2583         Map<Integer, Integer> firewallUidRules = new ArrayMap<>();
2584         doAnswer(arg -> {
2585             int[] uids = arg.getArgument(1);
2586             int[] rules = arg.getArgument(2);
2587             assertTrue(uids.length == rules.length);
2588 
2589             for (int i = 0; i < uids.length; ++i) {
2590                 firewallUidRules.put(uids[i], rules[i]);
2591             }
2592             return null;
2593         }).when(mNetworkManager).setFirewallUidRules(eq(FIREWALL_CHAIN_LOW_POWER_STANDBY),
2594                 any(int[].class), any(int[].class));
2595 
2596         internal.setLowPowerStandbyAllowlist(new int[] { UID_B });
2597         internal.setLowPowerStandbyActive(true);
2598         assertEquals(FIREWALL_RULE_ALLOW, firewallUidRules.get(UID_A).intValue());
2599         assertEquals(FIREWALL_RULE_ALLOW, firewallUidRules.get(UID_B).intValue());
2600         assertFalse(mService.isUidNetworkingBlocked(UID_A, false));
2601         assertFalse(mService.isUidNetworkingBlocked(UID_B, false));
2602         assertTrue(mService.isUidNetworkingBlocked(UID_C, false));
2603 
2604         internal.setLowPowerStandbyActive(false);
2605         assertFalse(mService.isUidNetworkingBlocked(UID_A, false));
2606         assertFalse(mService.isUidNetworkingBlocked(UID_B, false));
2607         assertFalse(mService.isUidNetworkingBlocked(UID_C, false));
2608     }
2609 
2610     @Test
testUpdateEffectiveBlockedReasons()2611     public void testUpdateEffectiveBlockedReasons() {
2612         final Map<Pair<Integer, Integer>, Integer> effectiveBlockedReasons = new HashMap<>();
2613         effectiveBlockedReasons.put(Pair.create(BLOCKED_REASON_NONE, ALLOWED_REASON_NONE),
2614                 BLOCKED_REASON_NONE);
2615 
2616         effectiveBlockedReasons.put(
2617                 Pair.create(BLOCKED_REASON_BATTERY_SAVER, ALLOWED_REASON_SYSTEM),
2618                 BLOCKED_REASON_NONE);
2619         effectiveBlockedReasons.put(Pair.create(BLOCKED_REASON_BATTERY_SAVER | BLOCKED_REASON_DOZE,
2620                 ALLOWED_REASON_SYSTEM), BLOCKED_REASON_NONE);
2621         effectiveBlockedReasons.put(
2622                 Pair.create(BLOCKED_METERED_REASON_DATA_SAVER, ALLOWED_METERED_REASON_SYSTEM),
2623                 BLOCKED_REASON_NONE);
2624         effectiveBlockedReasons.put(Pair.create(BLOCKED_METERED_REASON_DATA_SAVER
2625                         | BLOCKED_METERED_REASON_USER_RESTRICTED,
2626                 ALLOWED_METERED_REASON_SYSTEM), BLOCKED_REASON_NONE);
2627 
2628         effectiveBlockedReasons.put(
2629                 Pair.create(BLOCKED_REASON_BATTERY_SAVER | BLOCKED_METERED_REASON_DATA_SAVER,
2630                         ALLOWED_REASON_SYSTEM), BLOCKED_METERED_REASON_DATA_SAVER);
2631         effectiveBlockedReasons.put(
2632                 Pair.create(BLOCKED_REASON_APP_STANDBY | BLOCKED_METERED_REASON_USER_RESTRICTED,
2633                         ALLOWED_METERED_REASON_SYSTEM), BLOCKED_REASON_APP_STANDBY);
2634 
2635         effectiveBlockedReasons.put(
2636                 Pair.create(BLOCKED_REASON_BATTERY_SAVER, ALLOWED_REASON_FOREGROUND),
2637                 BLOCKED_REASON_NONE);
2638         effectiveBlockedReasons.put(Pair.create(BLOCKED_REASON_BATTERY_SAVER | BLOCKED_REASON_DOZE,
2639                 ALLOWED_REASON_FOREGROUND), BLOCKED_REASON_NONE);
2640         effectiveBlockedReasons.put(
2641                 Pair.create(BLOCKED_METERED_REASON_DATA_SAVER, ALLOWED_METERED_REASON_FOREGROUND),
2642                 BLOCKED_REASON_NONE);
2643         effectiveBlockedReasons.put(Pair.create(BLOCKED_METERED_REASON_DATA_SAVER
2644                         | BLOCKED_METERED_REASON_USER_RESTRICTED,
2645                 ALLOWED_METERED_REASON_FOREGROUND), BLOCKED_REASON_NONE);
2646         effectiveBlockedReasons.put(
2647                 Pair.create(BLOCKED_REASON_BATTERY_SAVER | BLOCKED_METERED_REASON_DATA_SAVER,
2648                         ALLOWED_REASON_FOREGROUND), BLOCKED_METERED_REASON_DATA_SAVER);
2649         effectiveBlockedReasons.put(Pair.create(BLOCKED_REASON_BATTERY_SAVER
2650                         | BLOCKED_METERED_REASON_USER_RESTRICTED,
2651                 ALLOWED_METERED_REASON_FOREGROUND), BLOCKED_REASON_BATTERY_SAVER);
2652 
2653         effectiveBlockedReasons.put(Pair.create(BLOCKED_REASON_LOW_POWER_STANDBY,
2654                 ALLOWED_REASON_FOREGROUND), BLOCKED_REASON_LOW_POWER_STANDBY);
2655         effectiveBlockedReasons.put(Pair.create(BLOCKED_REASON_LOW_POWER_STANDBY,
2656                 ALLOWED_REASON_TOP), BLOCKED_REASON_NONE);
2657         effectiveBlockedReasons.put(Pair.create(BLOCKED_REASON_LOW_POWER_STANDBY,
2658                 ALLOWED_REASON_LOW_POWER_STANDBY_ALLOWLIST), BLOCKED_REASON_NONE);
2659 
2660         effectiveBlockedReasons.put(Pair.create(BLOCKED_REASON_APP_BACKGROUND,
2661                 ALLOWED_REASON_NOT_IN_BACKGROUND), BLOCKED_REASON_NONE);
2662         effectiveBlockedReasons.put(Pair.create(BLOCKED_REASON_APP_BACKGROUND
2663                         | BLOCKED_REASON_BATTERY_SAVER, ALLOWED_REASON_NOT_IN_BACKGROUND),
2664                 BLOCKED_REASON_BATTERY_SAVER);
2665         effectiveBlockedReasons.put(Pair.create(BLOCKED_REASON_APP_BACKGROUND
2666                         | BLOCKED_REASON_DOZE, ALLOWED_REASON_NOT_IN_BACKGROUND),
2667                 BLOCKED_REASON_DOZE);
2668         effectiveBlockedReasons.put(Pair.create(BLOCKED_REASON_APP_BACKGROUND,
2669                         ALLOWED_REASON_RESTRICTED_MODE_PERMISSIONS), BLOCKED_REASON_APP_BACKGROUND);
2670         effectiveBlockedReasons.put(Pair.create(BLOCKED_REASON_APP_BACKGROUND,
2671                 ALLOWED_REASON_POWER_SAVE_ALLOWLIST), BLOCKED_REASON_NONE);
2672         effectiveBlockedReasons.put(Pair.create(BLOCKED_REASON_APP_BACKGROUND,
2673                 ALLOWED_REASON_POWER_SAVE_EXCEPT_IDLE_ALLOWLIST), BLOCKED_REASON_NONE);
2674 
2675         for (Map.Entry<Pair<Integer, Integer>, Integer> test : effectiveBlockedReasons.entrySet()) {
2676             final int expectedEffectiveBlockedReasons = test.getValue();
2677             final int blockedReasons = test.getKey().first;
2678             final int allowedReasons = test.getKey().second;
2679             final String errorMsg = "Expected="
2680                     + blockedReasonsToString(expectedEffectiveBlockedReasons)
2681                     + "; blockedReasons=" + blockedReasonsToString(blockedReasons)
2682                     + ", allowedReasons=" + allowedReasonsToString(allowedReasons);
2683             assertEquals(errorMsg, expectedEffectiveBlockedReasons,
2684                     getEffectiveBlockedReasons(blockedReasons, allowedReasons));
2685         }
2686     }
2687 
2688     @Test
2689     @NetPolicyXml("network-policy-mobile.xml")
testStartToSupportCarrierUsagePolicy()2690     public void testStartToSupportCarrierUsagePolicy() throws Exception {
2691         NetworkPolicy[] policies = mService.getNetworkPolicies(
2692                 mServiceContext.getOpPackageName());
2693         assertEquals("Unexpected number of network policies", 1, policies.length);
2694         NetworkPolicy actualPolicy = policies[0];
2695         assertEquals("Unexpected template match rule in network policies",
2696                 NetworkTemplate.MATCH_CARRIER,
2697                 actualPolicy.template.getMatchRule());
2698         assertTrue("Unexpected subscriberIds size in network policies",
2699                 actualPolicy.template.getSubscriberIds().size() > 0);
2700         assertEquals("Unexpected template meteredness in network policies",
2701                 METERED_YES, actualPolicy.template.getMeteredness());
2702     }
2703 
2704     @Test
2705     @NetPolicyXml("network-policy-wifi-with-subscriberId-match-rule-all-and-templateMetered-no.xml")
testSupportedCarrierUsagePolicy()2706     public void testSupportedCarrierUsagePolicy() throws Exception {
2707         NetworkPolicy[] policies = mService.getNetworkPolicies(
2708                 mServiceContext.getOpPackageName());
2709         assertEquals("Unexpected number of network policies", 1, policies.length);
2710         NetworkPolicy actualPolicy = policies[0];
2711         assertEquals("Unexpected template match rule in network policies",
2712                 MATCH_WIFI,
2713                 actualPolicy.template.getMatchRule());
2714         assertEquals("Unexpected subscriberIds size in network policies",
2715                 actualPolicy.template.getSubscriberIds().size(), 0);
2716         assertEquals("Unexpected template meteredness in network policies",
2717                 METERED_NO, actualPolicy.template.getMeteredness());
2718     }
2719 
2720     @Test
testNormalizeTemplate_duplicatedMergedImsiList()2721     public void testNormalizeTemplate_duplicatedMergedImsiList() {
2722         // This test leads to a Log.wtf, so skip it on eng builds. Otherwise, Log.wtf() would
2723         // result in this process getting killed.
2724         Assume.assumeFalse(Build.IS_ENG);
2725         final NetworkTemplate template = new NetworkTemplate.Builder(MATCH_CARRIER)
2726                 .setSubscriberIds(Set.of(TEST_IMSI)).build();
2727         final String[] mergedImsiGroup = new String[] {TEST_IMSI, TEST_IMSI};
2728         final ArrayList<String[]> mergedList = new ArrayList<>();
2729         mergedList.add(mergedImsiGroup);
2730         // Verify the duplicated items in the merged IMSI list won't crash the system.
2731         final NetworkTemplate result = normalizeTemplate(template, mergedList);
2732         assertEquals(template, result);
2733     }
2734 
formatBlockedStateError(int uid, int rule, boolean metered, boolean backgroundRestricted)2735     private String formatBlockedStateError(int uid, int rule, boolean metered,
2736             boolean backgroundRestricted) {
2737         return String.format(
2738                 "Unexpected BlockedState: (uid=%d, rule=%s, metered=%b, backgroundRestricted=%b)",
2739                 uid, uidRulesToString(rule), metered, backgroundRestricted);
2740     }
2741 
buildMonthlyDataPlan(ZonedDateTime start, long limitBytes)2742     private SubscriptionPlan buildMonthlyDataPlan(ZonedDateTime start, long limitBytes) {
2743         return SubscriptionPlan.Builder
2744                 .createRecurringMonthly(start)
2745                 .setDataLimit(limitBytes, LIMIT_BEHAVIOR_DISABLED)
2746                 .build();
2747     }
2748 
buildApplicationInfo(String label, int uid)2749     private ApplicationInfo buildApplicationInfo(String label, int uid) {
2750         final ApplicationInfo ai = new ApplicationInfo();
2751         ai.nonLocalizedLabel = label;
2752         ai.uid = uid;
2753         return ai;
2754     }
2755 
buildInstalledPackageList()2756     private List<AndroidPackage> buildInstalledPackageList() {
2757         final List<AndroidPackage> installedApps = new ArrayList<>();
2758         installedApps.add(createPackageMock(UID_A));
2759         installedApps.add(createPackageMock(UID_B));
2760         installedApps.add(createPackageMock(UID_C));
2761         return installedApps;
2762     }
2763 
createPackageMock(int uid)2764     private AndroidPackage createPackageMock(int uid) {
2765         final AndroidPackage androidPackage = mock(AndroidPackage.class);
2766         when(androidPackage.getUid()).thenReturn(uid);
2767         return androidPackage;
2768     }
2769 
buildUserInfoList()2770     private List<UserInfo> buildUserInfoList() {
2771         final List<UserInfo> users = new ArrayList<>();
2772         users.add(new UserInfo(USER_ID, "user1", 0));
2773         return users;
2774     }
2775 
buildLinkProperties(String iface)2776     private LinkProperties buildLinkProperties(String iface) {
2777         final LinkProperties lp = new LinkProperties();
2778         lp.setInterfaceName(iface);
2779         return lp;
2780     }
2781 
buildNetworkCapabilities(int subId, boolean roaming)2782     private NetworkCapabilities buildNetworkCapabilities(int subId, boolean roaming) {
2783         final NetworkCapabilities.Builder builder = new NetworkCapabilities.Builder();
2784         builder.addTransportType(TRANSPORT_CELLULAR);
2785         if (!roaming) {
2786             builder.addCapability(NET_CAPABILITY_NOT_ROAMING);
2787         }
2788         builder.setNetworkSpecifier(new TelephonyNetworkSpecifier.Builder()
2789                 .setSubscriptionId(subId).build());
2790         return builder.build();
2791     }
2792 
buildDefaultFakeCarrierPolicy()2793     private NetworkPolicy buildDefaultFakeCarrierPolicy() {
2794         NetworkPolicy p = mService.buildDefaultCarrierPolicy(FAKE_SUB_ID, FAKE_SUBSCRIBER_ID);
2795         // set a deterministic cycle date
2796         p.cycleRule = new RecurrenceRule(
2797                 p.cycleRule.start.withDayOfMonth(DEFAULT_CYCLE_DAY),
2798                 p.cycleRule.end, Period.ofMonths(1));
2799         return p;
2800     }
2801 
buildFakeCarrierPolicy(int cycleDay, long warningBytes, long limitBytes, boolean inferred)2802     private static NetworkPolicy buildFakeCarrierPolicy(int cycleDay, long warningBytes,
2803             long limitBytes, boolean inferred) {
2804         // TODO: Refactor this to use sTemplateCarrierMetered.
2805         final NetworkTemplate template = new NetworkTemplate.Builder(MATCH_CARRIER)
2806                 .setSubscriberIds(Set.of(FAKE_SUBSCRIBER_ID))
2807                 .setMeteredness(METERED_YES).build();
2808         return new NetworkPolicy(template, cycleDay, TimeZone.getDefault().getID(), warningBytes,
2809                 limitBytes, SNOOZE_NEVER, SNOOZE_NEVER, true, inferred);
2810     }
2811 
assertNetworkPolicyEquals(int expectedCycleDay, long expectedWarningBytes, long expectedLimitBytes, boolean expectedInferred)2812     private void assertNetworkPolicyEquals(int expectedCycleDay, long expectedWarningBytes,
2813             long expectedLimitBytes, boolean expectedInferred) {
2814         NetworkPolicy[] policies = mService.getNetworkPolicies(
2815                 mServiceContext.getOpPackageName());
2816         assertEquals("Unexpected number of network policies", 1, policies.length);
2817         NetworkPolicy actualPolicy = policies[0];
2818         NetworkPolicy expectedPolicy = buildFakeCarrierPolicy(expectedCycleDay,
2819                 expectedWarningBytes, expectedLimitBytes, expectedInferred);
2820         assertEquals(expectedPolicy, actualPolicy);
2821     }
2822 
parseTime(String time)2823     private static long parseTime(String time) {
2824         return ZonedDateTime.parse(time).toInstant().toEpochMilli();
2825     }
2826 
setNetworkPolicies(NetworkPolicy... policies)2827     private void setNetworkPolicies(NetworkPolicy... policies) {
2828         mService.setNetworkPolicies(policies);
2829     }
2830 
buildWifi()2831     private static NetworkStateSnapshot buildWifi() {
2832         WifiInfo mockWifiInfo = mock(WifiInfo.class);
2833         when(mockWifiInfo.makeCopy(anyLong())).thenReturn(mockWifiInfo);
2834         when(mockWifiInfo.getNetworkKey()).thenReturn(TEST_WIFI_NETWORK_KEY);
2835         final LinkProperties prop = new LinkProperties();
2836         prop.setInterfaceName(TEST_IFACE);
2837         final NetworkCapabilities networkCapabilities = new NetworkCapabilities.Builder()
2838                 .addTransportType(TRANSPORT_WIFI).setTransportInfo(mockWifiInfo).build();
2839         return new NetworkStateSnapshot(TEST_NETWORK, networkCapabilities, prop,
2840                 null /*subscriberId*/, TYPE_WIFI);
2841     }
2842 
expectHasInternetPermission(int uid, boolean hasIt)2843     private void expectHasInternetPermission(int uid, boolean hasIt) throws Exception {
2844         when(mIpm.checkUidPermission(Manifest.permission.INTERNET, uid)).thenReturn(
2845                 hasIt ? PackageManager.PERMISSION_GRANTED : PackageManager.PERMISSION_DENIED);
2846     }
2847 
expectHasUseRestrictedNetworksPermission(int uid, boolean hasIt)2848     private void expectHasUseRestrictedNetworksPermission(int uid, boolean hasIt) throws Exception {
2849         when(mIpm.checkUidPermission(CONNECTIVITY_USE_RESTRICTED_NETWORKS, uid)).thenReturn(
2850                 hasIt ? PackageManager.PERMISSION_GRANTED : PackageManager.PERMISSION_DENIED);
2851         when(mIpm.checkUidPermission(NETWORK_STACK, uid)).thenReturn(
2852                 PackageManager.PERMISSION_DENIED);
2853         when(mIpm.checkUidPermission(PERMISSION_MAINLINE_NETWORK_STACK, uid)).thenReturn(
2854                 PackageManager.PERMISSION_DENIED);
2855     }
2856 
expectNetworkStateSnapshot(boolean roaming)2857     private void expectNetworkStateSnapshot(boolean roaming) throws Exception {
2858         when(mCarrierConfigManager.getConfigForSubId(eq(TEST_SUB_ID)))
2859                 .thenReturn(mCarrierConfig);
2860         List<NetworkStateSnapshot> snapshots = List.of(new NetworkStateSnapshot(
2861                 TEST_NETWORK,
2862                 buildNetworkCapabilities(TEST_SUB_ID, roaming),
2863                 buildLinkProperties(TEST_IFACE), TEST_IMSI, TYPE_MOBILE));
2864         when(mConnManager.getAllNetworkStateSnapshots()).thenReturn(snapshots);
2865     }
2866 
expectDefaultCarrierConfig()2867     private void expectDefaultCarrierConfig() throws Exception {
2868         when(mCarrierConfigManager.getConfigForSubId(eq(TEST_SUB_ID)))
2869                 .thenReturn(CarrierConfigManager.getDefaultConfig());
2870     }
2871 
expectMobileDefaults()2872     private TelephonyManager expectMobileDefaults() throws Exception {
2873         TelephonyManager tmSub = setupTelephonySubscriptionManagers(TEST_SUB_ID, TEST_IMSI);
2874         doNothing().when(tmSub).setPolicyDataEnabled(anyBoolean());
2875         expectNetworkStateSnapshot(false /* roaming */);
2876         return tmSub;
2877     }
2878 
verifyAdvisePersistThreshold()2879     private void verifyAdvisePersistThreshold() throws Exception {
2880         verify(mStatsManager).setDefaultGlobalAlert(anyLong());
2881     }
2882 
assertTimeEquals(long expected, long actual)2883     private static void assertTimeEquals(long expected, long actual) {
2884         if (expected != actual) {
2885             fail("expected " + formatTime(expected) + " but was actually " + formatTime(actual));
2886         }
2887     }
2888 
formatTime(long millis)2889     private static String formatTime(long millis) {
2890         return Instant.ofEpochMilli(millis) + " [" + millis + "]";
2891     }
2892 
assertEqualsFuzzy(long expected, long actual, long fuzzy)2893     private static void assertEqualsFuzzy(long expected, long actual, long fuzzy) {
2894         final long low = expected - fuzzy;
2895         final long high = expected + fuzzy;
2896         if (actual < low || actual > high) {
2897             fail("value " + formatTime(actual) + " is outside [" + formatTime(low) + ","
2898                     + formatTime(high) + "]");
2899         }
2900     }
2901 
assertUnique(LinkedHashSet<Long> seen, Long value)2902     private static void assertUnique(LinkedHashSet<Long> seen, Long value) {
2903         if (!seen.add(value)) {
2904             fail("found duplicate time " + value + " in series " + seen.toString());
2905         }
2906     }
2907 
assertNotificationType(int expected, String actualTag)2908     private static void assertNotificationType(int expected, String actualTag) {
2909         assertEquals("notification type mismatch for '" + actualTag + "'",
2910                 Integer.toString(expected), actualTag.substring(actualTag.lastIndexOf(':') + 1));
2911     }
2912 
assertUidPolicy(int uid, int expected)2913     private void assertUidPolicy(int uid, int expected) {
2914         final int actual = mService.getUidPolicy(uid);
2915         if (expected != actual) {
2916             fail("Wrong policy for UID " + uid + ": expected " + uidPoliciesToString(expected)
2917                     + ", actual " + uidPoliciesToString(actual));
2918         }
2919     }
2920 
assertRestrictBackgroundAllowedUids(int... uids)2921     private void assertRestrictBackgroundAllowedUids(int... uids) {
2922         assertContainsInAnyOrder(mService.getUidsWithPolicy(POLICY_ALLOW_METERED_BACKGROUND), uids);
2923     }
2924 
assertRestrictBackgroundOn()2925     private void assertRestrictBackgroundOn() throws Exception {
2926         assertTrue("restrictBackground should be set", mService.getRestrictBackground());
2927     }
2928 
assertRestrictBackgroundOff()2929     private void assertRestrictBackgroundOff() throws Exception {
2930         assertFalse("restrictBackground should not be set", mService.getRestrictBackground());
2931     }
2932 
newRestrictBackgroundChangedFuture()2933     private FutureIntent newRestrictBackgroundChangedFuture() {
2934         return mServiceContext
2935                 .nextBroadcastIntent(ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED);
2936     }
2937 
assertRestrictBackgroundChangedReceived(Future<Intent> future, String expectedPackage)2938     private void assertRestrictBackgroundChangedReceived(Future<Intent> future,
2939             String expectedPackage) throws Exception {
2940         final String action = ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED;
2941         final Intent intent = future.get(5, TimeUnit.SECONDS);
2942         assertNotNull("Didn't get a " + action + "intent in 5 seconds");
2943         assertEquals("Wrong package on " + action + " intent",
2944                 expectedPackage, intent.getPackage());
2945     }
2946 
2947     // TODO: replace by Truth, Hamcrest, or a similar tool.
assertContainsInAnyOrder(int[] actual, int...expected)2948     private void assertContainsInAnyOrder(int[] actual, int...expected) {
2949         final StringBuilder errors = new StringBuilder();
2950         if (actual.length != expected.length) {
2951             errors.append("\tsize does not match\n");
2952         }
2953         final List<Integer> actualList =
2954                 Arrays.stream(actual).boxed().collect(Collectors.<Integer>toList());
2955         final List<Integer> expectedList =
2956                 Arrays.stream(expected).boxed().collect(Collectors.<Integer>toList());
2957         if (!actualList.containsAll(expectedList)) {
2958             errors.append("\tmissing elements on actual list\n");
2959         }
2960         if (!expectedList.containsAll(actualList)) {
2961             errors.append("\tmissing elements on expected list\n");
2962         }
2963         if (errors.length() > 0) {
2964             fail("assertContainsInAnyOrder(expected=" + Arrays.toString(expected)
2965                     + ", actual=" + Arrays.toString(actual) + ") failed: \n" + errors);
2966         }
2967     }
2968 
getElapsedRealtime()2969     private long getElapsedRealtime() {
2970         return mElapsedRealtime;
2971     }
2972 
setCurrentTimeMillis(long currentTimeMillis)2973     private void setCurrentTimeMillis(long currentTimeMillis) {
2974         RecurrenceRule.sClock = Clock.fixed(Instant.ofEpochMilli(currentTimeMillis),
2975                 ZoneId.systemDefault());
2976         mStartTime = currentTimeMillis;
2977         mElapsedRealtime = 0L;
2978     }
2979 
currentTimeMillis()2980     private long currentTimeMillis() {
2981         return mStartTime + mElapsedRealtime;
2982     }
2983 
incrementCurrentTime(long duration)2984     private void incrementCurrentTime(long duration) {
2985         mElapsedRealtime += duration;
2986     }
2987 
2988     private FutureIntent mRestrictBackgroundChanged;
2989 
postMsgAndWaitForCompletion()2990     private void postMsgAndWaitForCompletion() throws InterruptedException {
2991         final CountDownLatch latch = new CountDownLatch(1);
2992         mService.getHandlerForTesting().post(latch::countDown);
2993         if (!latch.await(5, TimeUnit.SECONDS)) {
2994             fail("Timed out waiting for the test msg to be handled");
2995         }
2996     }
2997 
2998     /**
2999      * This posts a blocking message to the service handler with the given delayMs and waits for it
3000      * to complete. This ensures that all messages posted before the given delayMs will also
3001      * have been executed before this method returns and can be verified in subsequent code.
3002      */
waitForDelayedMessageOnHandler(long delayMs)3003     private void waitForDelayedMessageOnHandler(long delayMs) throws InterruptedException {
3004         final CountDownLatch latch = new CountDownLatch(1);
3005         mService.getHandlerForTesting().postDelayed(latch::countDown, delayMs);
3006         if (!latch.await(delayMs + 5_000, TimeUnit.MILLISECONDS)) {
3007             fail("Timed out waiting for delayed msg to be handled");
3008         }
3009     }
3010 
setSubscriptionPlans(int subId, SubscriptionPlan[] plans, String callingPackage)3011     private void setSubscriptionPlans(int subId, SubscriptionPlan[] plans, String callingPackage)
3012             throws InterruptedException {
3013         mService.setSubscriptionPlans(subId, plans, 0, callingPackage);
3014         // setSubscriptionPlans() triggers async events, wait for those to be completed before
3015         // moving forward as they could interfere with the tests later.
3016         postMsgAndWaitForCompletion();
3017     }
3018 
setRestrictBackground(boolean flag)3019     private void setRestrictBackground(boolean flag) throws Exception {
3020         mService.setRestrictBackground(flag);
3021         assertEquals("restrictBackground not set", flag, mService.getRestrictBackground());
3022     }
3023 
3024     /**
3025      * Creates a mock and registers it to {@link LocalServices}.
3026      */
addLocalServiceMock(Class<T> clazz)3027     private static <T> T addLocalServiceMock(Class<T> clazz) {
3028         final T mock = mock(clazz);
3029         LocalServices.addService(clazz, mock);
3030         return mock;
3031     }
3032 
3033     /**
3034      * Creates a mock {@link TelephonyManager} and {@link SubscriptionManager}.
3035      *
3036      */
setupTelephonySubscriptionManagers(int subscriptionId, String subscriberId)3037     private TelephonyManager setupTelephonySubscriptionManagers(int subscriptionId,
3038             String subscriberId) {
3039         when(mSubscriptionManager.getActiveSubscriptionInfoList()).thenReturn(
3040                 createSubscriptionInfoList(subscriptionId));
3041         notifyDefaultAndActiveDataSubIdChange(subscriptionId, subscriptionId);
3042 
3043         TelephonyManager subTelephonyManager;
3044         subTelephonyManager = mock(TelephonyManager.class);
3045         when(subTelephonyManager.getSubscriptionId()).thenReturn(subscriptionId);
3046         when(subTelephonyManager.getSubscriberId()).thenReturn(subscriberId);
3047         when(mTelephonyManager.createForSubscriptionId(subscriptionId))
3048                 .thenReturn(subTelephonyManager);
3049         return subTelephonyManager;
3050     }
3051 
3052     /**
3053      * Telephony Manager callback notifies data sub Id changes.
3054      * @param defaultDataSubId The mock default data sub Id.
3055      * @param activeDataSubId The mock active data sub Id.
3056      */
notifyDefaultAndActiveDataSubIdChange(int defaultDataSubId, int activeDataSubId)3057     private void notifyDefaultAndActiveDataSubIdChange(int defaultDataSubId, int activeDataSubId) {
3058         mDeps.setDefaultAndActiveDataSubId(defaultDataSubId, activeDataSubId);
3059         mActiveDataSubIdListener.onActiveDataSubscriptionIdChanged(activeDataSubId);
3060     }
3061 
3062     /**
3063      * Creates mock {@link SubscriptionInfo} from subscription id.
3064      */
createSubscriptionInfoList(int subId)3065     private List<SubscriptionInfo> createSubscriptionInfoList(int subId) {
3066         final List<SubscriptionInfo> sub = new ArrayList<>();
3067         sub.add(createSubscriptionInfo(subId));
3068         return sub;
3069     }
3070 
3071     /**
3072      * Creates mock {@link SubscriptionInfo} from subscription id.
3073      */
createSubscriptionInfo(int subId)3074     private SubscriptionInfo createSubscriptionInfo(int subId) {
3075         return new SubscriptionInfo(subId, null, -1, null, null, -1, -1,
3076                 null, -1, null, null, null, null, false, null, null);
3077     }
3078 
3079     /**
3080      * Custom Mockito answer used to verify async {@link INetworkPolicyListener} calls.
3081      *
3082      * <p>Typical usage:
3083      * <pre><code>
3084      *    mPolicyListener.expect().someCallback(any());
3085      *    // do something on objects under test
3086      *    mPolicyListener.waitAndVerify().someCallback(eq(expectedValue));
3087      * </code></pre>
3088      */
3089     final class NetworkPolicyListenerAnswer implements Answer<Void> {
3090         private CountDownLatch latch;
3091         private final INetworkPolicyListener listener;
3092 
NetworkPolicyListenerAnswer(NetworkPolicyManagerService service)3093         NetworkPolicyListenerAnswer(NetworkPolicyManagerService service) {
3094             this.listener = mock(INetworkPolicyListener.class);
3095             // RemoteCallbackList needs a binder to use as key
3096             when(listener.asBinder()).thenReturn(new Binder());
3097             service.registerListener(listener);
3098         }
3099 
3100         @Override
answer(InvocationOnMock invocation)3101         public Void answer(InvocationOnMock invocation) throws Throwable {
3102             Log.d(TAG, "counting down on answer: " + invocation);
3103             latch.countDown();
3104             return null;
3105         }
3106 
expect()3107         INetworkPolicyListener expect() {
3108             assertNull("expect() called before waitAndVerify()", latch);
3109             latch = new CountDownLatch(1);
3110             return doAnswer(this).when(listener);
3111         }
3112 
waitAndVerify()3113         INetworkPolicyListener waitAndVerify() {
3114             assertNotNull("waitAndVerify() called before expect()", latch);
3115             try {
3116                 assertTrue("callback not called in 5 seconds", latch.await(5, TimeUnit.SECONDS));
3117             } catch (InterruptedException e) {
3118                 fail("Thread interrupted before callback called");
3119             } finally {
3120                 latch = null;
3121             }
3122             return verify(listener, atLeastOnce());
3123         }
3124 
verifyNotCalled()3125         INetworkPolicyListener verifyNotCalled() {
3126             return verify(listener, never());
3127         }
3128 
3129     }
3130 
setNetpolicyXml(Context context)3131     private void setNetpolicyXml(Context context) throws Exception {
3132         mPolicyDir = context.getFilesDir();
3133         if (mPolicyDir.exists()) {
3134             FsUtil.deleteContents(mPolicyDir);
3135         }
3136         if (!TextUtils.isEmpty(mNetpolicyXml)) {
3137             final String assetPath = NETPOLICY_DIR + "/" + mNetpolicyXml;
3138             final File netConfigFile = new File(mPolicyDir, "netpolicy.xml");
3139             Log.d(TAG, "Creating " + netConfigFile + " from asset " + assetPath);
3140             try (InputStream in = context.getResources().getAssets().open(assetPath);
3141                     OutputStream out = new FileOutputStream(netConfigFile)) {
3142                 Streams.copy(in, out);
3143             }
3144         }
3145     }
3146 
3147     /**
3148      * Annotation used to define the relative path of the {@code netpolicy.xml} file.
3149      */
3150     @Retention(RetentionPolicy.RUNTIME)
3151     @Target(ElementType.METHOD)
3152     public @interface NetPolicyXml {
value()3153         String value() default "";
3154     }
3155 
3156     /**
3157      * Rule used to set {@code mNetPolicyXml} according to the {@link NetPolicyXml} annotation.
3158      */
3159     public static class NetPolicyMethodRule implements MethodRule {
3160 
3161         @Override
apply(Statement base, FrameworkMethod method, Object target)3162         public Statement apply(Statement base, FrameworkMethod method, Object target) {
3163             for (Annotation annotation : method.getAnnotations()) {
3164                 if ((annotation instanceof NetPolicyXml)) {
3165                     final String path = ((NetPolicyXml) annotation).value();
3166                     if (!path.isEmpty()) {
3167                         ((NetworkPolicyManagerServiceTest) target).mNetpolicyXml = path;
3168                         break;
3169                     }
3170                 }
3171             }
3172             return base;
3173         }
3174     }
3175 }
3176