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