19599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey/*
29599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey * Copyright (C) 2011 The Android Open Source Project
39599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey *
49599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey * Licensed under the Apache License, Version 2.0 (the "License");
59599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey * you may not use this file except in compliance with the License.
69599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey * You may obtain a copy of the License at
79599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey *
89599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey *      http://www.apache.org/licenses/LICENSE-2.0
99599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey *
109599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey * Unless required by applicable law or agreed to in writing, software
119599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey * distributed under the License is distributed on an "AS IS" BASIS,
129599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey * See the License for the specific language governing permissions and
149599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey * limitations under the License.
159599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey */
169599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
179599cc5f21152860af9d18015b1398b50743da76Jeff Sharkeypackage com.android.server;
189599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
19f851d6dd2a15b74f63c85403afad0ed747f7311cErik Klineimport static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
2021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport static android.net.ConnectivityManager.TYPE_WIFI;
21ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VANimport static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING;
222e4714575ff7aac65a0e107cbf2dd03fa3affe95Jeff Sharkeyimport static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
23af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkeyimport static android.net.NetworkPolicy.LIMIT_DISABLED;
246ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijaziimport static android.net.NetworkPolicy.SNOOZE_NEVER;
25af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkeyimport static android.net.NetworkPolicy.WARNING_DISABLED;
2646b451fa7da6c0323e80616409cf467d5b1fd01fFelipe Lemeimport static android.net.NetworkPolicyManager.POLICY_ALLOW_METERED_BACKGROUND;
279599cc5f21152860af9d18015b1398b50743da76Jeff Sharkeyimport static android.net.NetworkPolicyManager.POLICY_NONE;
28fdfef57f498e3021a34342538aef9f1c7ccbae78Jeff Sharkeyimport static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND;
29e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Lemeimport static android.net.NetworkPolicyManager.uidPoliciesToString;
30e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkeyimport static android.net.NetworkStats.IFACE_ALL;
31e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkeyimport static android.net.NetworkStats.SET_ALL;
32e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkeyimport static android.net.NetworkStats.TAG_ALL;
336ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijaziimport static android.net.NetworkTemplate.buildTemplateMobileAll;
34ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VANimport static android.net.NetworkTemplate.buildTemplateWifi;
35241dde2306202e7655fdf41d5381f2874e47e108Jeff Sharkeyimport static android.net.TrafficStats.MB_IN_BYTES;
366ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijaziimport static android.telephony.CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED;
376ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijaziimport static android.telephony.CarrierConfigManager.DATA_CYCLE_THRESHOLD_DISABLED;
3853313d7e8153982f842910118371e1dc061248cdJeff Sharkeyimport static android.telephony.CarrierConfigManager.DATA_CYCLE_USE_PLATFORM_DEFAULT;
396ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijaziimport static android.telephony.CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG;
406ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijaziimport static android.telephony.CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG;
416ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijaziimport static android.telephony.CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT;
4236b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkeyimport static android.telephony.SubscriptionPlan.BYTES_UNLIMITED;
43bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkeyimport static android.telephony.SubscriptionPlan.LIMIT_BEHAVIOR_DISABLED;
449bf3150cfae03421c9dd237b46657714859d871cJeff Sharkeyimport static android.text.format.Time.TIMEZONE_UTC;
45ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme
4636b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkeyimport static com.android.server.net.NetworkPolicyManagerInternal.QUOTA_TYPE_JOBS;
4736b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkeyimport static com.android.server.net.NetworkPolicyManagerInternal.QUOTA_TYPE_MULTIPATH;
48ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VANimport static com.android.server.net.NetworkPolicyManagerService.OPPORTUNISTIC_QUOTA_UNKNOWN;
4941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkeyimport static com.android.server.net.NetworkPolicyManagerService.TYPE_LIMIT;
5041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkeyimport static com.android.server.net.NetworkPolicyManagerService.TYPE_LIMIT_SNOOZED;
51bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkeyimport static com.android.server.net.NetworkPolicyManagerService.TYPE_RAPID;
5241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkeyimport static com.android.server.net.NetworkPolicyManagerService.TYPE_WARNING;
5353313d7e8153982f842910118371e1dc061248cdJeff Sharkey
549f27e7ad34054e7e1d742845983a355eea63f205Felipe Lemeimport static org.junit.Assert.assertEquals;
559f27e7ad34054e7e1d742845983a355eea63f205Felipe Lemeimport static org.junit.Assert.assertFalse;
569f27e7ad34054e7e1d742845983a355eea63f205Felipe Lemeimport static org.junit.Assert.assertNotNull;
579f27e7ad34054e7e1d742845983a355eea63f205Felipe Lemeimport static org.junit.Assert.assertNull;
589f27e7ad34054e7e1d742845983a355eea63f205Felipe Lemeimport static org.junit.Assert.assertTrue;
599f27e7ad34054e7e1d742845983a355eea63f205Felipe Lemeimport static org.junit.Assert.fail;
6053313d7e8153982f842910118371e1dc061248cdJeff Sharkeyimport static org.mockito.ArgumentMatchers.any;
61543339fe6b01aaaf112b6b093bc34a7a7aa79a7eSudheer Shankaimport static org.mockito.ArgumentMatchers.anyBoolean;
6253313d7e8153982f842910118371e1dc061248cdJeff Sharkeyimport static org.mockito.ArgumentMatchers.anyInt;
6353313d7e8153982f842910118371e1dc061248cdJeff Sharkeyimport static org.mockito.ArgumentMatchers.anyLong;
6453313d7e8153982f842910118371e1dc061248cdJeff Sharkeyimport static org.mockito.ArgumentMatchers.anyString;
6553313d7e8153982f842910118371e1dc061248cdJeff Sharkeyimport static org.mockito.ArgumentMatchers.eq;
6653313d7e8153982f842910118371e1dc061248cdJeff Sharkeyimport static org.mockito.ArgumentMatchers.isA;
6753313d7e8153982f842910118371e1dc061248cdJeff Sharkeyimport static org.mockito.ArgumentMatchers.isNull;
6829c82ab242d50000d22e593c27153751c8c6b44ajackqdyuleiimport static org.mockito.Mockito.atLeast;
69ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Lemeimport static org.mockito.Mockito.atLeastOnce;
70ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Lemeimport static org.mockito.Mockito.doAnswer;
71ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VANimport static org.mockito.Mockito.doNothing;
72ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Lemeimport static org.mockito.Mockito.mock;
733d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Lemeimport static org.mockito.Mockito.never;
742e4714575ff7aac65a0e107cbf2dd03fa3affe95Jeff Sharkeyimport static org.mockito.Mockito.reset;
75ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Lemeimport static org.mockito.Mockito.verify;
76ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Lemeimport static org.mockito.Mockito.when;
77ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme
783d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Lemeimport android.Manifest;
79ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Lemeimport android.app.ActivityManager;
80e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shankaimport android.app.ActivityManagerInternal;
819599cc5f21152860af9d18015b1398b50743da76Jeff Sharkeyimport android.app.IActivityManager;
82ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Lemeimport android.app.IUidObserver;
8341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkeyimport android.app.Notification;
84bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkeyimport android.app.NotificationManager;
85ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Lemeimport android.app.usage.UsageStatsManagerInternal;
86ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Lemeimport android.content.Context;
879599cc5f21152860af9d18015b1398b50743da76Jeff Sharkeyimport android.content.Intent;
88ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Lemeimport android.content.pm.ApplicationInfo;
893d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Lemeimport android.content.pm.IPackageManager;
904414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkeyimport android.content.pm.PackageInfo;
919599cc5f21152860af9d18015b1398b50743da76Jeff Sharkeyimport android.content.pm.PackageManager;
924414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkeyimport android.content.pm.Signature;
933d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Lemeimport android.net.ConnectivityManager;
9421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport android.net.IConnectivityManager;
9541ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkeyimport android.net.INetworkManagementEventObserver;
969599cc5f21152860af9d18015b1398b50743da76Jeff Sharkeyimport android.net.INetworkPolicyListener;
9721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport android.net.LinkProperties;
982e4714575ff7aac65a0e107cbf2dd03fa3affe95Jeff Sharkeyimport android.net.Network;
99a1c92b7e8d534758d49c1808181aaa62f15357e3Stephen Chenimport android.net.NetworkCapabilities;
10021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport android.net.NetworkInfo;
10121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport android.net.NetworkInfo.DetailedState;
10221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport android.net.NetworkPolicy;
10321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport android.net.NetworkState;
10421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport android.net.NetworkStats;
1052e4714575ff7aac65a0e107cbf2dd03fa3affe95Jeff Sharkeyimport android.net.NetworkStatsHistory;
1061b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkeyimport android.net.NetworkTemplate;
1072e4714575ff7aac65a0e107cbf2dd03fa3affe95Jeff Sharkeyimport android.net.StringNetworkSpecifier;
1089599cc5f21152860af9d18015b1398b50743da76Jeff Sharkeyimport android.os.Binder;
10950fd36d7c38c40b087c8f3e3172478abe0c051d9Ashish Sharmaimport android.os.INetworkManagementService;
1106ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijaziimport android.os.PersistableBundle;
111ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Lemeimport android.os.PowerManagerInternal;
11229c82ab242d50000d22e593c27153751c8c6b44ajackqdyuleiimport android.os.PowerSaveState;
1136ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijaziimport android.os.RemoteException;
1149911a28adb3b1196fe912ff5b65b8d5cbc7321ecJeff Sharkeyimport android.os.SimpleClock;
115e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkeyimport android.os.SystemClock;
116f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackbornimport android.os.UserHandle;
1179f27e7ad34054e7e1d742845983a355eea63f205Felipe Lemeimport android.support.test.InstrumentationRegistry;
1189f27e7ad34054e7e1d742845983a355eea63f205Felipe Lemeimport android.support.test.runner.AndroidJUnit4;
1196ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijaziimport android.telephony.CarrierConfigManager;
1206ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijaziimport android.telephony.SubscriptionManager;
1212e4714575ff7aac65a0e107cbf2dd03fa3affe95Jeff Sharkeyimport android.telephony.SubscriptionPlan;
1226ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijaziimport android.telephony.TelephonyManager;
123bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkeyimport android.test.suitebuilder.annotation.MediumTest;
124e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Lemeimport android.text.TextUtils;
12521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport android.text.format.Time;
1262e4714575ff7aac65a0e107cbf2dd03fa3affe95Jeff Sharkeyimport android.util.DataUnit;
127ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Lemeimport android.util.Log;
1280fc6d03b628c8cbe80e3c2c14aaf8c6944b32d1eJeff Sharkeyimport android.util.Range;
12917bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkeyimport android.util.RecurrenceRule;
1309599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
1316ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijaziimport com.android.internal.telephony.PhoneConstants;
132281a17c9580de5c9898be7d9654d428801976511Lorenzo Colittiimport com.android.internal.util.test.BroadcastInterceptingContext;
133281a17c9580de5c9898be7d9654d428801976511Lorenzo Colittiimport com.android.internal.util.test.BroadcastInterceptingContext.FutureIntent;
134ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Lemeimport com.android.server.net.NetworkPolicyManagerInternal;
1359599cc5f21152860af9d18015b1398b50743da76Jeff Sharkeyimport com.android.server.net.NetworkPolicyManagerService;
136e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkeyimport com.android.server.net.NetworkStatsManagerInternal;
137ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme
138ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Lemeimport libcore.io.IoUtils;
139e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Lemeimport libcore.io.Streams;
140ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme
1414414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkeyimport com.google.common.util.concurrent.AbstractFuture;
1429599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
1439f27e7ad34054e7e1d742845983a355eea63f205Felipe Lemeimport org.junit.After;
1449f27e7ad34054e7e1d742845983a355eea63f205Felipe Lemeimport org.junit.Before;
145e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Lemeimport org.junit.Rule;
1469f27e7ad34054e7e1d742845983a355eea63f205Felipe Lemeimport org.junit.Test;
147e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Lemeimport org.junit.rules.MethodRule;
1489f27e7ad34054e7e1d742845983a355eea63f205Felipe Lemeimport org.junit.runner.RunWith;
149e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Lemeimport org.junit.runners.model.FrameworkMethod;
150e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Lemeimport org.junit.runners.model.Statement;
151ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Lemeimport org.mockito.ArgumentCaptor;
152ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Lemeimport org.mockito.Mock;
153ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Lemeimport org.mockito.MockitoAnnotations;
154ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Lemeimport org.mockito.invocation.InvocationOnMock;
155ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Lemeimport org.mockito.stubbing.Answer;
1569599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
15721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport java.io.File;
158e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Lemeimport java.io.FileOutputStream;
159e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Lemeimport java.io.InputStream;
160e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Lemeimport java.io.OutputStream;
161e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Lemeimport java.lang.annotation.Annotation;
162e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Lemeimport java.lang.annotation.ElementType;
163e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Lemeimport java.lang.annotation.Retention;
164e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Lemeimport java.lang.annotation.RetentionPolicy;
165e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Lemeimport java.lang.annotation.Target;
16617bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkeyimport java.time.Clock;
16753313d7e8153982f842910118371e1dc061248cdJeff Sharkeyimport java.time.Instant;
16817bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkeyimport java.time.Period;
16917bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkeyimport java.time.ZoneId;
1709911a28adb3b1196fe912ff5b65b8d5cbc7321ecJeff Sharkeyimport java.time.ZoneOffset;
17153313d7e8153982f842910118371e1dc061248cdJeff Sharkeyimport java.time.ZonedDateTime;
172e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Lemeimport java.util.Arrays;
1736ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijaziimport java.util.Calendar;
17453313d7e8153982f842910118371e1dc061248cdJeff Sharkeyimport java.util.Iterator;
175af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkeyimport java.util.LinkedHashSet;
176ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Lemeimport java.util.List;
177ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Lemeimport java.util.concurrent.CountDownLatch;
1784414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkeyimport java.util.concurrent.ExecutionException;
1799599cc5f21152860af9d18015b1398b50743da76Jeff Sharkeyimport java.util.concurrent.Future;
1804414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkeyimport java.util.concurrent.TimeUnit;
1814414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkeyimport java.util.concurrent.TimeoutException;
182e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Lemeimport java.util.stream.Collectors;
1838e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey
1849599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey/**
1859599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey * Tests for {@link NetworkPolicyManagerService}.
186b8d572eb86a24718002d51fa856823f8ad5ab2a5Felipe Leme *
187b8d572eb86a24718002d51fa856823f8ad5ab2a5Felipe Leme * <p>Typical usage:
188b8d572eb86a24718002d51fa856823f8ad5ab2a5Felipe Leme *
189b8d572eb86a24718002d51fa856823f8ad5ab2a5Felipe Leme * <pre><code>
190b8d572eb86a24718002d51fa856823f8ad5ab2a5Felipe Leme    m -j32 FrameworksServicesTests && adb install -r -g \
191b8d572eb86a24718002d51fa856823f8ad5ab2a5Felipe Leme    ${ANDROID_PRODUCT_OUT}/data/app/FrameworksServicesTests/FrameworksServicesTests.apk && \
192b8d572eb86a24718002d51fa856823f8ad5ab2a5Felipe Leme    adb shell am instrument -e class "com.android.server.NetworkPolicyManagerServiceTest" -w \
193b8d572eb86a24718002d51fa856823f8ad5ab2a5Felipe Leme    "com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner"
194b8d572eb86a24718002d51fa856823f8ad5ab2a5Felipe Leme * </code></pre>
1959599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey */
1969f27e7ad34054e7e1d742845983a355eea63f205Felipe Leme@RunWith(AndroidJUnit4.class)
1973d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme@MediumTest
1989f27e7ad34054e7e1d742845983a355eea63f205Felipe Lemepublic class NetworkPolicyManagerServiceTest {
1999599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey    private static final String TAG = "NetworkPolicyManagerServiceTest";
2009599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
20121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey    private static final long TEST_START = 1194220800000L;
20221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey    private static final String TEST_IFACE = "test0";
203e8914c36276710de50b347c1e6aecfa45d6a56cdJeff Sharkey    private static final String TEST_SSID = "AndroidAP";
2042e4714575ff7aac65a0e107cbf2dd03fa3affe95Jeff Sharkey    private static final String TEST_IMSI = "310210";
205bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey    private static final int TEST_SUB_ID = 42;
206bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey    private static final int TEST_NET_ID = 24;
20721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey
208ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN    private static NetworkTemplate sTemplateWifi = buildTemplateWifi(TEST_SSID);
209ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN    private static NetworkTemplate sTemplateMobileAll = buildTemplateMobileAll(TEST_IMSI);
2101b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
211e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme    /**
212e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme     * Path on assets where files used by {@link NetPolicyXml} are located.
213e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme     */
214e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme    private static final String NETPOLICY_DIR = "NetworkPolicyManagerServiceTest/netpolicy";
215e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme
2169599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey    private BroadcastInterceptingContext mServiceContext;
21721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey    private File mPolicyDir;
218ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme
219e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme    /**
220e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme     * Relative path of the XML file that will be used as {@code netpolicy.xml}.
221e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme     *
222e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme     * <p>Typically set through a {@link NetPolicyXml} annotation in the test method.
223e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme     */
224e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme    private String mNetpolicyXml;
225e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme
226ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme    private @Mock IActivityManager mActivityManager;
227ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme    private @Mock INetworkManagementService mNetworkManager;
228ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme    private @Mock IConnectivityManager mConnManager;
229ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN    private @Mock ConnectivityManager mConnectivityManager;
230bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey    private @Mock NotificationManager mNotifManager;
231ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme    private @Mock PackageManager mPackageManager;
2323d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    private @Mock IPackageManager mIpm;
2336ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi    private @Mock SubscriptionManager mSubscriptionManager;
2346ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi    private @Mock CarrierConfigManager mCarrierConfigManager;
2356ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi    private @Mock TelephonyManager mTelephonyManager;
236ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme
237ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN    private ArgumentCaptor<ConnectivityManager.NetworkCallback> mNetworkCallbackCaptor =
238ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN            ArgumentCaptor.forClass(ConnectivityManager.NetworkCallback.class);
239ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN
240e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey    private ActivityManagerInternal mActivityManagerInternal;
241e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey    private NetworkStatsManagerInternal mStatsService;
242e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shanka
243ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme    private IUidObserver mUidObserver;
24441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey    private INetworkManagementEventObserver mNetworkObserver;
2459599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
246ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme    private NetworkPolicyListenerAnswer mPolicyListener;
247ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme    private NetworkPolicyManagerService mService;
2489599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
249ed25ce6d598d7ed14f9b9859cdd2219bcc907f4cSudheer Shanka    /**
250ed25ce6d598d7ed14f9b9859cdd2219bcc907f4cSudheer Shanka     * In some of the tests while initializing NetworkPolicyManagerService,
251ed25ce6d598d7ed14f9b9859cdd2219bcc907f4cSudheer Shanka     * ACTION_RESTRICT_BACKGROUND_CHANGED is broadcasted. This is for capturing that broadcast.
252ed25ce6d598d7ed14f9b9859cdd2219bcc907f4cSudheer Shanka     */
253ed25ce6d598d7ed14f9b9859cdd2219bcc907f4cSudheer Shanka    private FutureIntent mFutureIntent;
254ed25ce6d598d7ed14f9b9859cdd2219bcc907f4cSudheer Shanka
2558e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey    private long mStartTime;
2568e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey    private long mElapsedRealtime;
2578e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey
258cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey    private static final int USER_ID = 0;
2596ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi    private static final int FAKE_SUB_ID = 3737373;
2606ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi    private static final String FAKE_SUBSCRIBER_ID = "FAKE_SUB_ID";
2616ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi    private static final int DEFAULT_CYCLE_DAY = 1;
2626ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi    private static final int INVALID_CARRIER_CONFIG_VALUE = -9999;
2636ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi    private long mDefaultWarningBytes; // filled in with the actual default before tests are run
2646ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi    private long mDefaultLimitBytes; // filled in with the actual default before tests are run
265cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey
266e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme    private static final int APP_ID_A = android.os.Process.FIRST_APPLICATION_UID + 4;
267e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme    private static final int APP_ID_B = android.os.Process.FIRST_APPLICATION_UID + 8;
268e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme    private static final int APP_ID_C = android.os.Process.FIRST_APPLICATION_UID + 15;
269e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme    private static final int APP_ID_D = android.os.Process.FIRST_APPLICATION_UID + 16;
270e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme    private static final int APP_ID_E = android.os.Process.FIRST_APPLICATION_UID + 23;
271e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme    private static final int APP_ID_F = android.os.Process.FIRST_APPLICATION_UID + 42;
272cae04a29da1334aa160ac44f7430411c23cebd1bJeff Sharkey
273f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackborn    private static final int UID_A = UserHandle.getUid(USER_ID, APP_ID_A);
274f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackborn    private static final int UID_B = UserHandle.getUid(USER_ID, APP_ID_B);
275e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme    private static final int UID_C = UserHandle.getUid(USER_ID, APP_ID_C);
276e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme    private static final int UID_D = UserHandle.getUid(USER_ID, APP_ID_D);
277e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme    private static final int UID_E = UserHandle.getUid(USER_ID, APP_ID_E);
278e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme    private static final int UID_F = UserHandle.getUid(USER_ID, APP_ID_F);
2799599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
280ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme    private static final String PKG_NAME_A = "name.is.A,pkg.A";
281e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey    private static final String PKG_NAME_B = "name.is.B,pkg.B";
282e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey    private static final String PKG_NAME_C = "name.is.C,pkg.C";
2839599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
284e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme    public final @Rule NetPolicyMethodRule mNetPolicyXmlRule = new NetPolicyMethodRule();
285e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme
2869911a28adb3b1196fe912ff5b65b8d5cbc7321ecJeff Sharkey    private final Clock mClock = new SimpleClock(ZoneOffset.UTC) {
2879911a28adb3b1196fe912ff5b65b8d5cbc7321ecJeff Sharkey        @Override
2889911a28adb3b1196fe912ff5b65b8d5cbc7321ecJeff Sharkey        public long millis() {
2899911a28adb3b1196fe912ff5b65b8d5cbc7321ecJeff Sharkey            return currentTimeMillis();
2909911a28adb3b1196fe912ff5b65b8d5cbc7321ecJeff Sharkey        }
2919911a28adb3b1196fe912ff5b65b8d5cbc7321ecJeff Sharkey    };
2929911a28adb3b1196fe912ff5b65b8d5cbc7321ecJeff Sharkey
293ed25ce6d598d7ed14f9b9859cdd2219bcc907f4cSudheer Shanka    private void registerLocalServices() {
2949f27e7ad34054e7e1d742845983a355eea63f205Felipe Leme        addLocalServiceMock(DeviceIdleController.LocalService.class);
295ed25ce6d598d7ed14f9b9859cdd2219bcc907f4cSudheer Shanka
2969f27e7ad34054e7e1d742845983a355eea63f205Felipe Leme        final UsageStatsManagerInternal usageStats =
2979f27e7ad34054e7e1d742845983a355eea63f205Felipe Leme                addLocalServiceMock(UsageStatsManagerInternal.class);
2989f27e7ad34054e7e1d742845983a355eea63f205Felipe Leme        when(usageStats.getIdleUidsForUser(anyInt())).thenReturn(new int[]{});
299ed25ce6d598d7ed14f9b9859cdd2219bcc907f4cSudheer Shanka
300e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shanka        mActivityManagerInternal = addLocalServiceMock(ActivityManagerInternal.class);
30129c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei
30229c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei        final PowerSaveState state = new PowerSaveState.Builder()
30329c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei                .setBatterySaverEnabled(false).build();
30429c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei        final PowerManagerInternal pmInternal = addLocalServiceMock(PowerManagerInternal.class);
30529c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei        when(pmInternal.getLowPowerState(anyInt())).thenReturn(state);
306e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey
307e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey        mStatsService = addLocalServiceMock(NetworkStatsManagerInternal.class);
3089f27e7ad34054e7e1d742845983a355eea63f205Felipe Leme    }
3099599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
3109f27e7ad34054e7e1d742845983a355eea63f205Felipe Leme    @Before
3119f27e7ad34054e7e1d742845983a355eea63f205Felipe Leme    public void callSystemReady() throws Exception {
312ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme        MockitoAnnotations.initMocks(this);
313ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme
3149f27e7ad34054e7e1d742845983a355eea63f205Felipe Leme        final Context context = InstrumentationRegistry.getContext();
315ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme
3168e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey        setCurrentTimeMillis(TEST_START);
3178e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey
318ed25ce6d598d7ed14f9b9859cdd2219bcc907f4cSudheer Shanka        registerLocalServices();
3196ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        // Intercept various broadcasts, and pretend that uids have packages.
3206ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        // Also return mock service instances for a few critical services.
321ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme        mServiceContext = new BroadcastInterceptingContext(context) {
3229599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey            @Override
3239599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey            public PackageManager getPackageManager() {
324ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme                return mPackageManager;
3259599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey            }
32641ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey
32741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey            @Override
32841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey            public void startActivity(Intent intent) {
32941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey                // ignored
33041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey            }
3316ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi
3326ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi            @Override
3336ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi            public Object getSystemService(String name) {
3346ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi                switch (name) {
3356ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi                    case Context.TELEPHONY_SUBSCRIPTION_SERVICE:
3366ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi                        return mSubscriptionManager;
3376ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi                    case Context.CARRIER_CONFIG_SERVICE:
3386ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi                        return mCarrierConfigManager;
3396ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi                    case Context.TELEPHONY_SERVICE:
3406ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi                        return mTelephonyManager;
341bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey                    case Context.NOTIFICATION_SERVICE:
342bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey                        return mNotifManager;
343ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN                    case Context.CONNECTIVITY_SERVICE:
344ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN                        return mConnectivityManager;
3456ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi                    default:
3466ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi                        return super.getSystemService(name);
3476ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi                }
3486ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi            }
3492e4714575ff7aac65a0e107cbf2dd03fa3affe95Jeff Sharkey
3502e4714575ff7aac65a0e107cbf2dd03fa3affe95Jeff Sharkey            @Override
3512e4714575ff7aac65a0e107cbf2dd03fa3affe95Jeff Sharkey            public void enforceCallingOrSelfPermission(String permission, String message) {
3522e4714575ff7aac65a0e107cbf2dd03fa3affe95Jeff Sharkey                // Assume that we're AID_SYSTEM
3532e4714575ff7aac65a0e107cbf2dd03fa3affe95Jeff Sharkey            }
3549599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        };
3559599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
356e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme        setNetpolicyXml(context);
35721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey
358ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme        doAnswer(new Answer<Void>() {
3599599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
360ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme            @Override
361ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme            public Void answer(InvocationOnMock invocation) throws Throwable {
362ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme                mUidObserver = (IUidObserver) invocation.getArguments()[0];
363ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme                Log.d(TAG, "set mUidObserver to " + mUidObserver);
364ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme                return null;
365ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme            }
3665614bf5a1ae4522dfc1a041f003cebc9b25c8b93Dianne Hackborn        }).when(mActivityManager).registerUidObserver(any(), anyInt(),
367b8d572eb86a24718002d51fa856823f8ad5ab2a5Felipe Leme                eq(ActivityManager.PROCESS_STATE_UNKNOWN), isNull(String.class));
3689599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
369ed25ce6d598d7ed14f9b9859cdd2219bcc907f4cSudheer Shanka        mFutureIntent = newRestrictBackgroundChangedFuture();
370e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey        mService = new NetworkPolicyManagerService(mServiceContext, mActivityManager,
3719911a28adb3b1196fe912ff5b65b8d5cbc7321ecJeff Sharkey                mNetworkManager, mIpm, mClock, mPolicyDir, true);
372ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme        mService.bindConnectivityManager(mConnManager);
373ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme        mPolicyListener = new NetworkPolicyListenerAnswer(mService);
3749599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
375ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme        // Sets some common expectations.
376ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme        when(mPackageManager.getPackageInfo(anyString(), anyInt())).thenAnswer(
377ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme                new Answer<PackageInfo>() {
37841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey
379ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme                    @Override
380ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme                    public PackageInfo answer(InvocationOnMock invocation) throws Throwable {
381ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme                        final String packageName = (String) invocation.getArguments()[0];
382ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme                        final PackageInfo info = new PackageInfo();
383ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme                        final Signature signature;
384ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme                        if ("android".equals(packageName)) {
385ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme                            signature = new Signature("F00D");
386ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme                        } else {
387ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme                            signature = new Signature("DEAD");
388ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme                        }
389ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme                        info.signatures = new Signature[] {
390ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme                            signature
391ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme                        };
392ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme                        return info;
393ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme                    }
394ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme                });
395ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme        when(mPackageManager.getApplicationInfoAsUser(anyString(), anyInt(), anyInt()))
396ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme                .thenReturn(new ApplicationInfo());
397ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme        when(mPackageManager.getPackagesForUid(UID_A)).thenReturn(new String[] {PKG_NAME_A});
398e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey        when(mPackageManager.getPackagesForUid(UID_B)).thenReturn(new String[] {PKG_NAME_B});
399e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey        when(mPackageManager.getPackagesForUid(UID_C)).thenReturn(new String[] {PKG_NAME_C});
400e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey        when(mPackageManager.getApplicationInfo(eq(PKG_NAME_A), anyInt()))
401e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey                .thenReturn(buildApplicationInfo(PKG_NAME_A));
402e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey        when(mPackageManager.getApplicationInfo(eq(PKG_NAME_B), anyInt()))
403e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey                .thenReturn(buildApplicationInfo(PKG_NAME_B));
404e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey        when(mPackageManager.getApplicationInfo(eq(PKG_NAME_C), anyInt()))
405e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey                .thenReturn(buildApplicationInfo(PKG_NAME_C));
406ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme        when(mNetworkManager.isBandwidthControlEnabled()).thenReturn(true);
407543339fe6b01aaaf112b6b093bc34a7a7aa79a7eSudheer Shanka        when(mNetworkManager.setDataSaverModeEnabled(anyBoolean())).thenReturn(true);
408ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN        doNothing().when(mConnectivityManager)
409ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN                .registerNetworkCallback(any(), mNetworkCallbackCaptor.capture());
4109599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
411ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme        // Prepare NPMS.
412311b9fac00c9298479340244ffedf4825e0a7756Fyodor Kupolov        mService.systemReady(mService.networkScoreAndNetworkManagementServiceReady());
4139599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
414ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme        // catch INetworkManagementEventObserver during systemReady()
4153d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        final ArgumentCaptor<INetworkManagementEventObserver> networkObserver =
416ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme              ArgumentCaptor.forClass(INetworkManagementEventObserver.class);
417ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme        verify(mNetworkManager).registerObserver(networkObserver.capture());
41841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        mNetworkObserver = networkObserver.getValue();
4196ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi
4206ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        NetworkPolicy defaultPolicy = mService.buildDefaultMobilePolicy(0, "");
4216ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        mDefaultWarningBytes = defaultPolicy.warningBytes;
4226ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        mDefaultLimitBytes = defaultPolicy.limitBytes;
4239599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey    }
4249599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
4259f27e7ad34054e7e1d742845983a355eea63f205Felipe Leme    @After
4269f27e7ad34054e7e1d742845983a355eea63f205Felipe Leme    public void removeFiles() throws Exception {
42721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        for (File file : mPolicyDir.listFiles()) {
42821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey            file.delete();
42921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        }
4309f27e7ad34054e7e1d742845983a355eea63f205Felipe Leme    }
43121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey
4329f27e7ad34054e7e1d742845983a355eea63f205Felipe Leme    @After
4339f27e7ad34054e7e1d742845983a355eea63f205Felipe Leme    public void unregisterLocalServices() throws Exception {
4349f27e7ad34054e7e1d742845983a355eea63f205Felipe Leme        // Registered by NetworkPolicyManagerService's constructor.
435ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme        LocalServices.removeServiceForTest(NetworkPolicyManagerInternal.class);
436ed25ce6d598d7ed14f9b9859cdd2219bcc907f4cSudheer Shanka
437ed25ce6d598d7ed14f9b9859cdd2219bcc907f4cSudheer Shanka        // Added in registerLocalServices()
438ed25ce6d598d7ed14f9b9859cdd2219bcc907f4cSudheer Shanka        LocalServices.removeServiceForTest(ActivityManagerInternal.class);
439ed25ce6d598d7ed14f9b9859cdd2219bcc907f4cSudheer Shanka        LocalServices.removeServiceForTest(PowerManagerInternal.class);
440ed25ce6d598d7ed14f9b9859cdd2219bcc907f4cSudheer Shanka        LocalServices.removeServiceForTest(DeviceIdleController.LocalService.class);
441ed25ce6d598d7ed14f9b9859cdd2219bcc907f4cSudheer Shanka        LocalServices.removeServiceForTest(UsageStatsManagerInternal.class);
442e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey        LocalServices.removeServiceForTest(NetworkStatsManagerInternal.class);
4439599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey    }
4449599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
44553313d7e8153982f842910118371e1dc061248cdJeff Sharkey    @After
44653313d7e8153982f842910118371e1dc061248cdJeff Sharkey    public void resetClock() throws Exception {
44717bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey        RecurrenceRule.sClock = Clock.systemDefaultZone();
44853313d7e8153982f842910118371e1dc061248cdJeff Sharkey    }
44953313d7e8153982f842910118371e1dc061248cdJeff Sharkey
450e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme    @Test
4513d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    public void testTurnRestrictBackgroundOn() throws Exception {
4523d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        assertRestrictBackgroundOff(); // Sanity check.
4533d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        final FutureIntent futureIntent = newRestrictBackgroundChangedFuture();
4543d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        setRestrictBackground(true);
4553d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        assertRestrictBackgroundChangedReceived(futureIntent, null);
4563d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    }
4573d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme
4583d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    @Test
4593d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    @NetPolicyXml("restrict-background-on.xml")
4603d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    public void testTurnRestrictBackgroundOff() throws Exception {
4613d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        assertRestrictBackgroundOn(); // Sanity check.
462ed25ce6d598d7ed14f9b9859cdd2219bcc907f4cSudheer Shanka        assertRestrictBackgroundChangedReceived(mFutureIntent, null);
4633d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        final FutureIntent futureIntent = newRestrictBackgroundChangedFuture();
4643d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        setRestrictBackground(false);
4653d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        assertRestrictBackgroundChangedReceived(futureIntent, null);
4663d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    }
4673d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme
4683d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    /**
4693d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme     * Adds whitelist when restrict background is on - app should receive an intent.
4703d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme     */
4713d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    @Test
4723d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    @NetPolicyXml("restrict-background-on.xml")
4733d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    public void testAddRestrictBackgroundWhitelist_restrictBackgroundOn() throws Exception {
4743d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        assertRestrictBackgroundOn(); // Sanity check.
475ed25ce6d598d7ed14f9b9859cdd2219bcc907f4cSudheer Shanka        assertRestrictBackgroundChangedReceived(mFutureIntent, null);
4763d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        addRestrictBackgroundWhitelist(true);
4773d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    }
4783d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme
4793d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    /**
4803d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme     * Adds whitelist when restrict background is off - app should not receive an intent.
4813d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme     */
4823d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    @Test
4833d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    public void testAddRestrictBackgroundWhitelist_restrictBackgroundOff() throws Exception {
4843d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        assertRestrictBackgroundOff(); // Sanity check.
4853d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        addRestrictBackgroundWhitelist(false);
4863d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    }
4873d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme
4883d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    private void addRestrictBackgroundWhitelist(boolean expectIntent) throws Exception {
48957e3d310913ff61ae63c66fcf3d7b64ab9d741a6Felipe Leme        // Sanity checks.
49057e3d310913ff61ae63c66fcf3d7b64ab9d741a6Felipe Leme        assertWhitelistUids();
49157e3d310913ff61ae63c66fcf3d7b64ab9d741a6Felipe Leme        assertUidPolicy(UID_A, POLICY_NONE);
49257e3d310913ff61ae63c66fcf3d7b64ab9d741a6Felipe Leme
4933d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        final FutureIntent futureIntent = newRestrictBackgroundChangedFuture();
4940ecfcd1e3a158ab5ee54d822d1a1166b15ba7a3cFelipe Leme        mPolicyListener.expect().onUidPoliciesChanged(anyInt(), anyInt());
4953d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme
49657e3d310913ff61ae63c66fcf3d7b64ab9d741a6Felipe Leme        mService.setUidPolicy(UID_A, POLICY_ALLOW_METERED_BACKGROUND);
4973d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme
4983d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        assertWhitelistUids(UID_A);
49957e3d310913ff61ae63c66fcf3d7b64ab9d741a6Felipe Leme        assertUidPolicy(UID_A, POLICY_ALLOW_METERED_BACKGROUND);
5000ecfcd1e3a158ab5ee54d822d1a1166b15ba7a3cFelipe Leme        mPolicyListener.waitAndVerify()
5010ecfcd1e3a158ab5ee54d822d1a1166b15ba7a3cFelipe Leme                .onUidPoliciesChanged(APP_ID_A, POLICY_ALLOW_METERED_BACKGROUND);
5023d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        if (expectIntent) {
5033d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme            assertRestrictBackgroundChangedReceived(futureIntent, PKG_NAME_A);
5043d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        } else {
5053d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme            futureIntent.assertNotReceived();
5063d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        }
5073d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    }
5083d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme
5093d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    /**
5103d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme     * Removes whitelist when restrict background is on - app should receive an intent.
5113d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme     */
5123d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    @Test
5133d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    @NetPolicyXml("uidA-whitelisted-restrict-background-on.xml")
5143d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    public void testRemoveRestrictBackgroundWhitelist_restrictBackgroundOn() throws Exception {
5153d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        assertRestrictBackgroundOn(); // Sanity check.
516ed25ce6d598d7ed14f9b9859cdd2219bcc907f4cSudheer Shanka        assertRestrictBackgroundChangedReceived(mFutureIntent, null);
5173d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        removeRestrictBackgroundWhitelist(true);
5183d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    }
5193d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme
5203d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    /**
5213d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme     * Removes whitelist when restrict background is off - app should not receive an intent.
5223d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme     */
5233d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    @Test
5243d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    @NetPolicyXml("uidA-whitelisted-restrict-background-off.xml")
5253d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    public void testRemoveRestrictBackgroundWhitelist_restrictBackgroundOff() throws Exception {
5263d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        assertRestrictBackgroundOff(); // Sanity check.
5273d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        removeRestrictBackgroundWhitelist(false);
5283d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    }
5293d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme
53029c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei    @Test
53129c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei    public void testLowPowerModeObserver_ListenersRegistered()
53229c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei            throws Exception {
53329c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei        PowerManagerInternal pmInternal = LocalServices.getService(PowerManagerInternal.class);
53429c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei
53529c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei        verify(pmInternal, atLeast(2)).registerLowPowerModeObserver(any());
53629c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei    }
53729c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei
53829c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei    @Test
53929c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei    public void updateRestrictBackgroundByLowPowerMode_RestrictOnBeforeBsm_RestrictOnAfterBsm()
54029c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei            throws Exception {
54129c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei        setRestrictBackground(true);
54229c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei        PowerSaveState stateOn = new PowerSaveState.Builder()
54329c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei                .setGlobalBatterySaverEnabled(true)
54429c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei                .setBatterySaverEnabled(false)
54529c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei                .build();
54629c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei        mService.updateRestrictBackgroundByLowPowerModeUL(stateOn);
54729c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei
54829c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei        // RestrictBackground should be on even though battery saver want to turn it off
549e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey        assertTrue(mService.getRestrictBackground());
55029c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei
55129c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei        PowerSaveState stateOff = new PowerSaveState.Builder()
55229c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei                .setGlobalBatterySaverEnabled(false)
55329c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei                .setBatterySaverEnabled(false)
55429c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei                .build();
55529c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei        mService.updateRestrictBackgroundByLowPowerModeUL(stateOff);
55629c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei
55729c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei        // RestrictBackground should be on, following its previous state
558e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey        assertTrue(mService.getRestrictBackground());
55929c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei    }
56029c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei
56129c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei    @Test
56229c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei    public void updateRestrictBackgroundByLowPowerMode_RestrictOffBeforeBsm_RestrictOffAfterBsm()
56329c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei            throws Exception {
56429c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei        setRestrictBackground(false);
56529c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei        PowerSaveState stateOn = new PowerSaveState.Builder()
56629c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei                .setGlobalBatterySaverEnabled(true)
56729c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei                .setBatterySaverEnabled(true)
56829c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei                .build();
56929c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei
57029c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei        mService.updateRestrictBackgroundByLowPowerModeUL(stateOn);
57129c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei
57229c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei        // RestrictBackground should be turned on because of battery saver
573e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey        assertTrue(mService.getRestrictBackground());
57429c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei
57529c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei        PowerSaveState stateOff = new PowerSaveState.Builder()
57629c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei                .setGlobalBatterySaverEnabled(false)
57729c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei                .setBatterySaverEnabled(false)
57829c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei                .build();
57929c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei        mService.updateRestrictBackgroundByLowPowerModeUL(stateOff);
58029c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei
58129c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei        // RestrictBackground should be off, following its previous state
582e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey        assertFalse(mService.getRestrictBackground());
58329c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei    }
58429c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei
58529c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei    @Test
58629c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei    public void updateRestrictBackgroundByLowPowerMode_StatusChangedInBsm_DoNotRestore()
58729c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei            throws Exception {
58829c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei        setRestrictBackground(true);
58929c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei        PowerSaveState stateOn = new PowerSaveState.Builder()
59029c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei                .setGlobalBatterySaverEnabled(true)
59129c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei                .setBatterySaverEnabled(true)
59229c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei                .build();
59329c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei        mService.updateRestrictBackgroundByLowPowerModeUL(stateOn);
59429c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei
59529c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei        // RestrictBackground should still be on
596e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey        assertTrue(mService.getRestrictBackground());
59729c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei
59829c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei        // User turns off RestrictBackground manually
59929c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei        setRestrictBackground(false);
60029c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei        PowerSaveState stateOff = new PowerSaveState.Builder().setBatterySaverEnabled(
60129c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei                false).build();
60229c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei        mService.updateRestrictBackgroundByLowPowerModeUL(stateOff);
60329c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei
60429c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei        // RestrictBackground should be off because user changes it manually
605e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey        assertFalse(mService.getRestrictBackground());
60629c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei    }
60729c82ab242d50000d22e593c27153751c8c6b44ajackqdyulei
6083d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    private void removeRestrictBackgroundWhitelist(boolean expectIntent) throws Exception {
60957e3d310913ff61ae63c66fcf3d7b64ab9d741a6Felipe Leme        // Sanity checks.
61057e3d310913ff61ae63c66fcf3d7b64ab9d741a6Felipe Leme        assertWhitelistUids(UID_A);
61157e3d310913ff61ae63c66fcf3d7b64ab9d741a6Felipe Leme        assertUidPolicy(UID_A, POLICY_ALLOW_METERED_BACKGROUND);
61257e3d310913ff61ae63c66fcf3d7b64ab9d741a6Felipe Leme
6133d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        final FutureIntent futureIntent = newRestrictBackgroundChangedFuture();
6140ecfcd1e3a158ab5ee54d822d1a1166b15ba7a3cFelipe Leme        mPolicyListener.expect().onUidPoliciesChanged(anyInt(), anyInt());
6153d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme
61657e3d310913ff61ae63c66fcf3d7b64ab9d741a6Felipe Leme        mService.setUidPolicy(UID_A, POLICY_NONE);
6173d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme
6183d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        assertWhitelistUids();
61957e3d310913ff61ae63c66fcf3d7b64ab9d741a6Felipe Leme        assertUidPolicy(UID_A, POLICY_NONE);
6200ecfcd1e3a158ab5ee54d822d1a1166b15ba7a3cFelipe Leme        mPolicyListener.waitAndVerify().onUidPoliciesChanged(APP_ID_A, POLICY_NONE);
6213d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        if (expectIntent) {
6223d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme            assertRestrictBackgroundChangedReceived(futureIntent, PKG_NAME_A);
6233d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        } else {
6243d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme            futureIntent.assertNotReceived();
6253d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        }
6263d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    }
6273d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme
6283d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    /**
62957e3d310913ff61ae63c66fcf3d7b64ab9d741a6Felipe Leme     * Adds blacklist when restrict background is on - app should not receive an intent.
6303d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme     */
6313d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    @Test
6323d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    @NetPolicyXml("restrict-background-on.xml")
6333d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    public void testAddRestrictBackgroundBlacklist_restrictBackgroundOn() throws Exception {
6343d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        assertRestrictBackgroundOn(); // Sanity check.
635ed25ce6d598d7ed14f9b9859cdd2219bcc907f4cSudheer Shanka        assertRestrictBackgroundChangedReceived(mFutureIntent, null);
63657e3d310913ff61ae63c66fcf3d7b64ab9d741a6Felipe Leme        addRestrictBackgroundBlacklist(false);
6373d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    }
6383d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme
6393d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    /**
6403d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme     * Adds blacklist when restrict background is off - app should receive an intent.
6413d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme     */
6423d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    @Test
6433d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    public void testAddRestrictBackgroundBlacklist_restrictBackgroundOff() throws Exception {
6443d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        assertRestrictBackgroundOff(); // Sanity check.
6453d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        addRestrictBackgroundBlacklist(true);
6463d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    }
6473d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme
6483d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    private void addRestrictBackgroundBlacklist(boolean expectIntent) throws Exception {
6493d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        assertUidPolicy(UID_A, POLICY_NONE); // Sanity check.
6503d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        final FutureIntent futureIntent = newRestrictBackgroundChangedFuture();
6510ecfcd1e3a158ab5ee54d822d1a1166b15ba7a3cFelipe Leme        mPolicyListener.expect().onUidPoliciesChanged(anyInt(), anyInt());
6523d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme
6533d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        mService.setUidPolicy(UID_A, POLICY_REJECT_METERED_BACKGROUND);
6543d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme
6553d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        assertUidPolicy(UID_A, POLICY_REJECT_METERED_BACKGROUND);
6560ecfcd1e3a158ab5ee54d822d1a1166b15ba7a3cFelipe Leme        mPolicyListener.waitAndVerify()
6570ecfcd1e3a158ab5ee54d822d1a1166b15ba7a3cFelipe Leme                .onUidPoliciesChanged(APP_ID_A, POLICY_REJECT_METERED_BACKGROUND);
6583d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        if (expectIntent) {
6593d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme            assertRestrictBackgroundChangedReceived(futureIntent, PKG_NAME_A);
6603d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        } else {
6613d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme            futureIntent.assertNotReceived();
6623d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        }
6633d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    }
6643d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme
6653d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    /**
66657e3d310913ff61ae63c66fcf3d7b64ab9d741a6Felipe Leme     * Removes blacklist when restrict background is on - app should not receive an intent.
6673d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme     */
6683d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    @Test
6693d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    @NetPolicyXml("uidA-blacklisted-restrict-background-on.xml")
6703d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    public void testRemoveRestrictBackgroundBlacklist_restrictBackgroundOn() throws Exception {
6713d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        assertRestrictBackgroundOn(); // Sanity check.
672ed25ce6d598d7ed14f9b9859cdd2219bcc907f4cSudheer Shanka        assertRestrictBackgroundChangedReceived(mFutureIntent, null);
67357e3d310913ff61ae63c66fcf3d7b64ab9d741a6Felipe Leme        removeRestrictBackgroundBlacklist(false);
6743d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    }
6753d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme
6763d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    /**
6773d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme     * Removes blacklist when restrict background is off - app should receive an intent.
6783d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme     */
6793d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    @Test
6803d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    @NetPolicyXml("uidA-blacklisted-restrict-background-off.xml")
6813d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    public void testRemoveRestrictBackgroundBlacklist_restrictBackgroundOff() throws Exception {
6823d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        assertRestrictBackgroundOff(); // Sanity check.
6833d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        removeRestrictBackgroundBlacklist(true);
6843d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    }
6853d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme
6863d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    private void removeRestrictBackgroundBlacklist(boolean expectIntent) throws Exception {
6873d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        assertUidPolicy(UID_A, POLICY_REJECT_METERED_BACKGROUND); // Sanity check.
6883d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        final FutureIntent futureIntent = newRestrictBackgroundChangedFuture();
6890ecfcd1e3a158ab5ee54d822d1a1166b15ba7a3cFelipe Leme        mPolicyListener.expect().onUidPoliciesChanged(anyInt(), anyInt());
6903d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme
6913d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        mService.setUidPolicy(UID_A, POLICY_NONE);
6923d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme
6933d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        assertUidPolicy(UID_A, POLICY_NONE);
6940ecfcd1e3a158ab5ee54d822d1a1166b15ba7a3cFelipe Leme        mPolicyListener.waitAndVerify()
6950ecfcd1e3a158ab5ee54d822d1a1166b15ba7a3cFelipe Leme                .onUidPoliciesChanged(APP_ID_A, POLICY_NONE);
6963d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        if (expectIntent) {
6973d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme            assertRestrictBackgroundChangedReceived(futureIntent, PKG_NAME_A);
6983d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        } else {
6993d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme            futureIntent.assertNotReceived();
7003d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        }
7013d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    }
7023d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme
70351a63642408bb5daeb9450eed98162c8a5463846Felipe Leme    @Test
704c08ecdf36f88c3f24cd34f6da5e4984fb2a63fcbFelipe Leme    @NetPolicyXml("uidA-blacklisted-restrict-background-on.xml")
7053d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    public void testBlacklistedAppIsNotNotifiedWhenRestrictBackgroundIsOn() throws Exception {
7063d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        // Sanity checks.
7073d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        assertRestrictBackgroundOn();
708ed25ce6d598d7ed14f9b9859cdd2219bcc907f4cSudheer Shanka        assertRestrictBackgroundChangedReceived(mFutureIntent, null);
7093d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        assertUidPolicy(UID_A, POLICY_REJECT_METERED_BACKGROUND);
7103d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme
7113d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        final FutureIntent futureIntent = newRestrictBackgroundChangedFuture();
7123d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        setRestrictBackground(true);
7133d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        futureIntent.assertNotReceived();
7143d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    }
7153d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme
71651a63642408bb5daeb9450eed98162c8a5463846Felipe Leme    @Test
717c08ecdf36f88c3f24cd34f6da5e4984fb2a63fcbFelipe Leme    @NetPolicyXml("uidA-whitelisted-restrict-background-on.xml")
7183d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    public void testWhitelistedAppIsNotNotifiedWhenRestrictBackgroundIsOn() throws Exception {
7193d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        // Sanity checks.
720c08ecdf36f88c3f24cd34f6da5e4984fb2a63fcbFelipe Leme        assertRestrictBackgroundOn();
721ed25ce6d598d7ed14f9b9859cdd2219bcc907f4cSudheer Shanka        assertRestrictBackgroundChangedReceived(mFutureIntent, null);
7223d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        assertWhitelistUids(UID_A);
7233d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme
7243d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        final FutureIntent futureIntent = newRestrictBackgroundChangedFuture();
7253d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        setRestrictBackground(true);
7263d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        futureIntent.assertNotReceived();
7273d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    }
7283d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme
72984d156bc1a2de8d02a8d1a635d2b61b1783caef6Andreas Gampe    @Test
73057e3d310913ff61ae63c66fcf3d7b64ab9d741a6Felipe Leme    @NetPolicyXml("uidA-whitelisted-restrict-background-on.xml")
73157e3d310913ff61ae63c66fcf3d7b64ab9d741a6Felipe Leme    public void testWhitelistedAppIsNotifiedWhenBlacklisted() throws Exception {
73257e3d310913ff61ae63c66fcf3d7b64ab9d741a6Felipe Leme        // Sanity checks.
73357e3d310913ff61ae63c66fcf3d7b64ab9d741a6Felipe Leme        assertRestrictBackgroundOn();
734ed25ce6d598d7ed14f9b9859cdd2219bcc907f4cSudheer Shanka        assertRestrictBackgroundChangedReceived(mFutureIntent, null);
73557e3d310913ff61ae63c66fcf3d7b64ab9d741a6Felipe Leme        assertWhitelistUids(UID_A);
73657e3d310913ff61ae63c66fcf3d7b64ab9d741a6Felipe Leme
73757e3d310913ff61ae63c66fcf3d7b64ab9d741a6Felipe Leme        final FutureIntent futureIntent = newRestrictBackgroundChangedFuture();
73857e3d310913ff61ae63c66fcf3d7b64ab9d741a6Felipe Leme        mService.setUidPolicy(UID_A, POLICY_REJECT_METERED_BACKGROUND);
73957e3d310913ff61ae63c66fcf3d7b64ab9d741a6Felipe Leme        assertRestrictBackgroundChangedReceived(futureIntent, PKG_NAME_A);
74057e3d310913ff61ae63c66fcf3d7b64ab9d741a6Felipe Leme    }
74157e3d310913ff61ae63c66fcf3d7b64ab9d741a6Felipe Leme
7423d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    @Test
743e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme    @NetPolicyXml("restrict-background-lists-whitelist-format.xml")
744e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme    public void testRestrictBackgroundLists_whitelistFormat() throws Exception {
74546b451fa7da6c0323e80616409cf467d5b1fd01fFelipe Leme        restrictBackgroundListsTest();
74646b451fa7da6c0323e80616409cf467d5b1fd01fFelipe Leme    }
74746b451fa7da6c0323e80616409cf467d5b1fd01fFelipe Leme
74846b451fa7da6c0323e80616409cf467d5b1fd01fFelipe Leme    @Test
74946b451fa7da6c0323e80616409cf467d5b1fd01fFelipe Leme    @NetPolicyXml("restrict-background-lists-uid-policy-format.xml")
75046b451fa7da6c0323e80616409cf467d5b1fd01fFelipe Leme    public void testRestrictBackgroundLists_uidPolicyFormat() throws Exception {
75146b451fa7da6c0323e80616409cf467d5b1fd01fFelipe Leme        restrictBackgroundListsTest();
75246b451fa7da6c0323e80616409cf467d5b1fd01fFelipe Leme    }
75346b451fa7da6c0323e80616409cf467d5b1fd01fFelipe Leme
75446b451fa7da6c0323e80616409cf467d5b1fd01fFelipe Leme    private void restrictBackgroundListsTest() throws Exception {
7558546a444800b331d0c373b12aa196050049c57bbFelipe Leme        // UIds that are whitelisted.
75646b451fa7da6c0323e80616409cf467d5b1fd01fFelipe Leme        assertWhitelistUids(UID_A, UID_B, UID_C);
75746b451fa7da6c0323e80616409cf467d5b1fd01fFelipe Leme        assertUidPolicy(UID_A, POLICY_ALLOW_METERED_BACKGROUND);
75846b451fa7da6c0323e80616409cf467d5b1fd01fFelipe Leme        assertUidPolicy(UID_B, POLICY_ALLOW_METERED_BACKGROUND);
75946b451fa7da6c0323e80616409cf467d5b1fd01fFelipe Leme        assertUidPolicy(UID_C, POLICY_ALLOW_METERED_BACKGROUND);
760e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme
7618546a444800b331d0c373b12aa196050049c57bbFelipe Leme        // UIDs that are blacklisted.
762e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme        assertUidPolicy(UID_D, POLICY_NONE);
763e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme        assertUidPolicy(UID_E, POLICY_REJECT_METERED_BACKGROUND);
7648546a444800b331d0c373b12aa196050049c57bbFelipe Leme
7658546a444800b331d0c373b12aa196050049c57bbFelipe Leme        // UIDS that have legacy policies.
76646b451fa7da6c0323e80616409cf467d5b1fd01fFelipe Leme        assertUidPolicy(UID_F, 2); // POLICY_ALLOW_BACKGROUND_BATTERY_SAVE
76746b451fa7da6c0323e80616409cf467d5b1fd01fFelipe Leme
76846b451fa7da6c0323e80616409cf467d5b1fd01fFelipe Leme        // Remove whitelist.
76957e3d310913ff61ae63c66fcf3d7b64ab9d741a6Felipe Leme        mService.setUidPolicy(UID_A, POLICY_NONE);
77046b451fa7da6c0323e80616409cf467d5b1fd01fFelipe Leme        assertUidPolicy(UID_A, POLICY_NONE);
77146b451fa7da6c0323e80616409cf467d5b1fd01fFelipe Leme        assertWhitelistUids(UID_B, UID_C);
77246b451fa7da6c0323e80616409cf467d5b1fd01fFelipe Leme
77346b451fa7da6c0323e80616409cf467d5b1fd01fFelipe Leme        // Add whitelist when blacklisted.
77457e3d310913ff61ae63c66fcf3d7b64ab9d741a6Felipe Leme        mService.setUidPolicy(UID_E, POLICY_ALLOW_METERED_BACKGROUND);
77546b451fa7da6c0323e80616409cf467d5b1fd01fFelipe Leme        assertUidPolicy(UID_E, POLICY_ALLOW_METERED_BACKGROUND);
77646b451fa7da6c0323e80616409cf467d5b1fd01fFelipe Leme        assertWhitelistUids(UID_B, UID_C, UID_E);
77746b451fa7da6c0323e80616409cf467d5b1fd01fFelipe Leme
77846b451fa7da6c0323e80616409cf467d5b1fd01fFelipe Leme        // Add blacklist when whitelisted.
77946b451fa7da6c0323e80616409cf467d5b1fd01fFelipe Leme        mService.setUidPolicy(UID_B, POLICY_REJECT_METERED_BACKGROUND);
78046b451fa7da6c0323e80616409cf467d5b1fd01fFelipe Leme        assertUidPolicy(UID_B, POLICY_REJECT_METERED_BACKGROUND);
78146b451fa7da6c0323e80616409cf467d5b1fd01fFelipe Leme        assertWhitelistUids(UID_C, UID_E);
78246b451fa7da6c0323e80616409cf467d5b1fd01fFelipe Leme    }
78346b451fa7da6c0323e80616409cf467d5b1fd01fFelipe Leme
78446b451fa7da6c0323e80616409cf467d5b1fd01fFelipe Leme    /**
78546b451fa7da6c0323e80616409cf467d5b1fd01fFelipe Leme     * Tests scenario where an UID had {@code restrict-background} and {@code uid-policy} tags.
78646b451fa7da6c0323e80616409cf467d5b1fd01fFelipe Leme     */
78746b451fa7da6c0323e80616409cf467d5b1fd01fFelipe Leme    @Test
78846b451fa7da6c0323e80616409cf467d5b1fd01fFelipe Leme    @NetPolicyXml("restrict-background-lists-mixed-format.xml")
78946b451fa7da6c0323e80616409cf467d5b1fd01fFelipe Leme    public void testRestrictBackgroundLists_mixedFormat() throws Exception {
79046b451fa7da6c0323e80616409cf467d5b1fd01fFelipe Leme        assertWhitelistUids(UID_A, UID_C, UID_D);
79146b451fa7da6c0323e80616409cf467d5b1fd01fFelipe Leme        assertUidPolicy(UID_A, POLICY_ALLOW_METERED_BACKGROUND);
79257e3d310913ff61ae63c66fcf3d7b64ab9d741a6Felipe Leme        assertUidPolicy(UID_B, POLICY_REJECT_METERED_BACKGROUND); // Blacklist prevails.
79346b451fa7da6c0323e80616409cf467d5b1fd01fFelipe Leme        assertUidPolicy(UID_C, (POLICY_ALLOW_METERED_BACKGROUND | 2));
79446b451fa7da6c0323e80616409cf467d5b1fd01fFelipe Leme        assertUidPolicy(UID_D, POLICY_ALLOW_METERED_BACKGROUND);
795e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme    }
796e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme
7976f51a0afe9237d36c374d5c202842292b9ba2a46Felipe Leme    @Test
7986f51a0afe9237d36c374d5c202842292b9ba2a46Felipe Leme    @NetPolicyXml("uids-with-mixed-policies.xml")
7996f51a0afe9237d36c374d5c202842292b9ba2a46Felipe Leme    public void testGetUidsWithPolicy() throws Exception {
80003f9029bed18338eaca0741eb95649cffb0f1874Felipe Leme        assertContainsInAnyOrder(mService.getUidsWithPolicy(POLICY_NONE));
8016f51a0afe9237d36c374d5c202842292b9ba2a46Felipe Leme        assertContainsInAnyOrder(mService.getUidsWithPolicy(POLICY_REJECT_METERED_BACKGROUND),
8026f51a0afe9237d36c374d5c202842292b9ba2a46Felipe Leme                UID_B, UID_D);
8036f51a0afe9237d36c374d5c202842292b9ba2a46Felipe Leme        assertContainsInAnyOrder(mService.getUidsWithPolicy(POLICY_ALLOW_METERED_BACKGROUND),
8046f51a0afe9237d36c374d5c202842292b9ba2a46Felipe Leme                UID_E, UID_F);
8056f51a0afe9237d36c374d5c202842292b9ba2a46Felipe Leme        // Legacy (POLICY_ALLOW_BACKGROUND_BATTERY_SAVE)
8066f51a0afe9237d36c374d5c202842292b9ba2a46Felipe Leme        assertContainsInAnyOrder(mService.getUidsWithPolicy(2),
8076f51a0afe9237d36c374d5c202842292b9ba2a46Felipe Leme                UID_C, UID_D, UID_F);
8086f51a0afe9237d36c374d5c202842292b9ba2a46Felipe Leme    }
8096f51a0afe9237d36c374d5c202842292b9ba2a46Felipe Leme
8100ecfcd1e3a158ab5ee54d822d1a1166b15ba7a3cFelipe Leme    // NOTE: testPolicyChangeTriggersListener() is too superficial, they
811ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme    // don't check for side-effects (like calls to NetworkManagementService) neither cover all
812ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme    // different modes (Data Saver, Battery Saver, Doze, App idle, etc...).
813ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme    // These scenarios are extensively tested on CTS' HostsideRestrictBackgroundNetworkTests.
8149f27e7ad34054e7e1d742845983a355eea63f205Felipe Leme    @Test
815ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme    public void testUidForeground() throws Exception {
816ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme        // push all uids into background
817ed25ce6d598d7ed14f9b9859cdd2219bcc907f4cSudheer Shanka        callOnUidStateChanged(UID_A, ActivityManager.PROCESS_STATE_SERVICE, 0);
818ed25ce6d598d7ed14f9b9859cdd2219bcc907f4cSudheer Shanka        callOnUidStateChanged(UID_B, ActivityManager.PROCESS_STATE_SERVICE, 0);
8199599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        assertFalse(mService.isUidForeground(UID_A));
8209599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        assertFalse(mService.isUidForeground(UID_B));
8219599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
822ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme        // push one of the uids into foreground
823ed25ce6d598d7ed14f9b9859cdd2219bcc907f4cSudheer Shanka        callOnUidStateChanged(UID_A, ActivityManager.PROCESS_STATE_TOP, 0);
8249599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        assertTrue(mService.isUidForeground(UID_A));
8259599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        assertFalse(mService.isUidForeground(UID_B));
8269599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
8279599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        // and swap another uid into foreground
828ed25ce6d598d7ed14f9b9859cdd2219bcc907f4cSudheer Shanka        callOnUidStateChanged(UID_A, ActivityManager.PROCESS_STATE_SERVICE, 0);
829ed25ce6d598d7ed14f9b9859cdd2219bcc907f4cSudheer Shanka        callOnUidStateChanged(UID_B, ActivityManager.PROCESS_STATE_TOP, 0);
8309599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        assertFalse(mService.isUidForeground(UID_A));
8319599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey        assertTrue(mService.isUidForeground(UID_B));
8329599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey    }
8339599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey
83453313d7e8153982f842910118371e1dc061248cdJeff Sharkey    private static long computeLastCycleBoundary(long currentTime, NetworkPolicy policy) {
83517bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey        RecurrenceRule.sClock = Clock.fixed(Instant.ofEpochMilli(currentTime),
83617bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey                ZoneId.systemDefault());
8370fc6d03b628c8cbe80e3c2c14aaf8c6944b32d1eJeff Sharkey        final Iterator<Range<ZonedDateTime>> it = policy.cycleIterator();
83853313d7e8153982f842910118371e1dc061248cdJeff Sharkey        while (it.hasNext()) {
8390fc6d03b628c8cbe80e3c2c14aaf8c6944b32d1eJeff Sharkey            final Range<ZonedDateTime> cycle = it.next();
8400fc6d03b628c8cbe80e3c2c14aaf8c6944b32d1eJeff Sharkey            if (cycle.getLower().toInstant().toEpochMilli() < currentTime) {
8410fc6d03b628c8cbe80e3c2c14aaf8c6944b32d1eJeff Sharkey                return cycle.getLower().toInstant().toEpochMilli();
84253313d7e8153982f842910118371e1dc061248cdJeff Sharkey            }
84353313d7e8153982f842910118371e1dc061248cdJeff Sharkey        }
84453313d7e8153982f842910118371e1dc061248cdJeff Sharkey        throw new IllegalStateException(
84553313d7e8153982f842910118371e1dc061248cdJeff Sharkey                "Failed to find current cycle for " + policy + " at " + currentTime);
84653313d7e8153982f842910118371e1dc061248cdJeff Sharkey    }
84753313d7e8153982f842910118371e1dc061248cdJeff Sharkey
84853313d7e8153982f842910118371e1dc061248cdJeff Sharkey    private static long computeNextCycleBoundary(long currentTime, NetworkPolicy policy) {
84917bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey        RecurrenceRule.sClock = Clock.fixed(Instant.ofEpochMilli(currentTime),
85017bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey                ZoneId.systemDefault());
8510fc6d03b628c8cbe80e3c2c14aaf8c6944b32d1eJeff Sharkey        return policy.cycleIterator().next().getUpper().toInstant().toEpochMilli();
85253313d7e8153982f842910118371e1dc061248cdJeff Sharkey    }
85353313d7e8153982f842910118371e1dc061248cdJeff Sharkey
8549f27e7ad34054e7e1d742845983a355eea63f205Felipe Leme    @Test
85521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey    public void testLastCycleBoundaryThisMonth() throws Exception {
85621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        // assume cycle day of "5th", which should be in same month
85721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        final long currentTime = parseTime("2007-11-14T00:00:00.000Z");
85821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        final long expectedCycle = parseTime("2007-11-05T00:00:00.000Z");
85921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey
86041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        final NetworkPolicy policy = new NetworkPolicy(
8619bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey                sTemplateWifi, 5, TIMEZONE_UTC, 1024L, 1024L, false);
86221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        final long actualCycle = computeLastCycleBoundary(currentTime, policy);
863af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey        assertTimeEquals(expectedCycle, actualCycle);
86421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey    }
86521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey
8669f27e7ad34054e7e1d742845983a355eea63f205Felipe Leme    @Test
86721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey    public void testLastCycleBoundaryLastMonth() throws Exception {
86821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        // assume cycle day of "20th", which should be in last month
86921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        final long currentTime = parseTime("2007-11-14T00:00:00.000Z");
87021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        final long expectedCycle = parseTime("2007-10-20T00:00:00.000Z");
87121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey
87241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        final NetworkPolicy policy = new NetworkPolicy(
8739bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey                sTemplateWifi, 20, TIMEZONE_UTC, 1024L, 1024L, false);
87421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        final long actualCycle = computeLastCycleBoundary(currentTime, policy);
875af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey        assertTimeEquals(expectedCycle, actualCycle);
87621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey    }
87721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey
8789f27e7ad34054e7e1d742845983a355eea63f205Felipe Leme    @Test
87921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey    public void testLastCycleBoundaryThisMonthFebruary() throws Exception {
88021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        // assume cycle day of "30th" in february; should go to january
88121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        final long currentTime = parseTime("2007-02-14T00:00:00.000Z");
88221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        final long expectedCycle = parseTime("2007-01-30T00:00:00.000Z");
88321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey
88441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        final NetworkPolicy policy = new NetworkPolicy(
8859bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey                sTemplateWifi, 30, TIMEZONE_UTC, 1024L, 1024L, false);
88621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        final long actualCycle = computeLastCycleBoundary(currentTime, policy);
887af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey        assertTimeEquals(expectedCycle, actualCycle);
88821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey    }
88921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey
8909f27e7ad34054e7e1d742845983a355eea63f205Felipe Leme    @Test
89121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey    public void testLastCycleBoundaryLastMonthFebruary() throws Exception {
89221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        // assume cycle day of "30th" in february, which should clamp
89321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        final long currentTime = parseTime("2007-03-14T00:00:00.000Z");
89453313d7e8153982f842910118371e1dc061248cdJeff Sharkey        final long expectedCycle = parseTime("2007-02-28T23:59:59.999Z");
89521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey
89641ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        final NetworkPolicy policy = new NetworkPolicy(
8979bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey                sTemplateWifi, 30, TIMEZONE_UTC, 1024L, 1024L, false);
89821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        final long actualCycle = computeLastCycleBoundary(currentTime, policy);
899af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey        assertTimeEquals(expectedCycle, actualCycle);
900af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey    }
901af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey
9029f27e7ad34054e7e1d742845983a355eea63f205Felipe Leme    @Test
9039bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey    public void testCycleBoundaryLeapYear() throws Exception {
9049bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey        final NetworkPolicy policy = new NetworkPolicy(
9059bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey                sTemplateWifi, 29, TIMEZONE_UTC, 1024L, 1024L, false);
9069bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey
9079bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey        assertTimeEquals(parseTime("2012-01-29T00:00:00.000Z"),
9089bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey                computeNextCycleBoundary(parseTime("2012-01-14T00:00:00.000Z"), policy));
9099bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey        assertTimeEquals(parseTime("2012-02-29T00:00:00.000Z"),
9109bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey                computeNextCycleBoundary(parseTime("2012-02-14T00:00:00.000Z"), policy));
9119bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey        assertTimeEquals(parseTime("2012-02-29T00:00:00.000Z"),
9129bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey                computeLastCycleBoundary(parseTime("2012-03-14T00:00:00.000Z"), policy));
9139bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey        assertTimeEquals(parseTime("2012-03-29T00:00:00.000Z"),
9149bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey                computeNextCycleBoundary(parseTime("2012-03-14T00:00:00.000Z"), policy));
9159bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey
9169bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey        assertTimeEquals(parseTime("2007-01-29T00:00:00.000Z"),
9179bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey                computeNextCycleBoundary(parseTime("2007-01-14T00:00:00.000Z"), policy));
91853313d7e8153982f842910118371e1dc061248cdJeff Sharkey        assertTimeEquals(parseTime("2007-02-28T23:59:59.999Z"),
9199bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey                computeNextCycleBoundary(parseTime("2007-02-14T00:00:00.000Z"), policy));
92053313d7e8153982f842910118371e1dc061248cdJeff Sharkey        assertTimeEquals(parseTime("2007-02-28T23:59:59.999Z"),
9219bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey                computeLastCycleBoundary(parseTime("2007-03-14T00:00:00.000Z"), policy));
9229bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey        assertTimeEquals(parseTime("2007-03-29T00:00:00.000Z"),
9239bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey                computeNextCycleBoundary(parseTime("2007-03-14T00:00:00.000Z"), policy));
9249bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey    }
9259bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey
9269f27e7ad34054e7e1d742845983a355eea63f205Felipe Leme    @Test
9279bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey    public void testNextCycleTimezoneAfterUtc() throws Exception {
9289bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey        // US/Central is UTC-6
9299bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey        final NetworkPolicy policy = new NetworkPolicy(
9309bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey                sTemplateWifi, 10, "US/Central", 1024L, 1024L, false);
9319bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey        assertTimeEquals(parseTime("2012-01-10T06:00:00.000Z"),
9329bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey                computeNextCycleBoundary(parseTime("2012-01-05T00:00:00.000Z"), policy));
9339bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey    }
9349bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey
9359f27e7ad34054e7e1d742845983a355eea63f205Felipe Leme    @Test
9369bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey    public void testNextCycleTimezoneBeforeUtc() throws Exception {
9379bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey        // Israel is UTC+2
9389bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey        final NetworkPolicy policy = new NetworkPolicy(
9399bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey                sTemplateWifi, 10, "Israel", 1024L, 1024L, false);
9409bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey        assertTimeEquals(parseTime("2012-01-09T22:00:00.000Z"),
9419bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey                computeNextCycleBoundary(parseTime("2012-01-05T00:00:00.000Z"), policy));
9429bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey    }
9439bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey
9449f27e7ad34054e7e1d742845983a355eea63f205Felipe Leme    @Test
9451539905b4621f94b0a1a215407a71034da806247Jeff Sharkey    public void testCycleTodayJanuary() throws Exception {
9461539905b4621f94b0a1a215407a71034da806247Jeff Sharkey        final NetworkPolicy policy = new NetworkPolicy(
9471539905b4621f94b0a1a215407a71034da806247Jeff Sharkey                sTemplateWifi, 14, "US/Pacific", 1024L, 1024L, false);
9481539905b4621f94b0a1a215407a71034da806247Jeff Sharkey
9491539905b4621f94b0a1a215407a71034da806247Jeff Sharkey        assertTimeEquals(parseTime("2013-01-14T00:00:00.000-08:00"),
9501539905b4621f94b0a1a215407a71034da806247Jeff Sharkey                computeNextCycleBoundary(parseTime("2013-01-13T23:59:59.000-08:00"), policy));
9511539905b4621f94b0a1a215407a71034da806247Jeff Sharkey        assertTimeEquals(parseTime("2013-02-14T00:00:00.000-08:00"),
9521539905b4621f94b0a1a215407a71034da806247Jeff Sharkey                computeNextCycleBoundary(parseTime("2013-01-14T00:00:01.000-08:00"), policy));
9531539905b4621f94b0a1a215407a71034da806247Jeff Sharkey        assertTimeEquals(parseTime("2013-02-14T00:00:00.000-08:00"),
9541539905b4621f94b0a1a215407a71034da806247Jeff Sharkey                computeNextCycleBoundary(parseTime("2013-01-14T15:11:00.000-08:00"), policy));
9551539905b4621f94b0a1a215407a71034da806247Jeff Sharkey
9561539905b4621f94b0a1a215407a71034da806247Jeff Sharkey        assertTimeEquals(parseTime("2012-12-14T00:00:00.000-08:00"),
9571539905b4621f94b0a1a215407a71034da806247Jeff Sharkey                computeLastCycleBoundary(parseTime("2013-01-13T23:59:59.000-08:00"), policy));
9581539905b4621f94b0a1a215407a71034da806247Jeff Sharkey        assertTimeEquals(parseTime("2013-01-14T00:00:00.000-08:00"),
9591539905b4621f94b0a1a215407a71034da806247Jeff Sharkey                computeLastCycleBoundary(parseTime("2013-01-14T00:00:01.000-08:00"), policy));
9601539905b4621f94b0a1a215407a71034da806247Jeff Sharkey        assertTimeEquals(parseTime("2013-01-14T00:00:00.000-08:00"),
9611539905b4621f94b0a1a215407a71034da806247Jeff Sharkey                computeLastCycleBoundary(parseTime("2013-01-14T15:11:00.000-08:00"), policy));
9621539905b4621f94b0a1a215407a71034da806247Jeff Sharkey    }
9631539905b4621f94b0a1a215407a71034da806247Jeff Sharkey
9649f27e7ad34054e7e1d742845983a355eea63f205Felipe Leme    @Test
96521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey    public void testNetworkPolicyAppliedCycleLastMonth() throws Exception {
96621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        NetworkState[] state = null;
96721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        NetworkStats stats = null;
96821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey
96921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        final int CYCLE_DAY = 15;
97053313d7e8153982f842910118371e1dc061248cdJeff Sharkey        final long NOW = parseTime("2007-03-10T00:00Z");
97153313d7e8153982f842910118371e1dc061248cdJeff Sharkey        final long CYCLE_START = parseTime("2007-02-15T00:00Z");
97253313d7e8153982f842910118371e1dc061248cdJeff Sharkey        final long CYCLE_END = parseTime("2007-03-15T00:00Z");
97321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey
97453313d7e8153982f842910118371e1dc061248cdJeff Sharkey        setCurrentTimeMillis(NOW);
9758e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey
97621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        // first, pretend that wifi network comes online. no policy active,
97721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        // which means we shouldn't push limit to interface.
97821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        state = new NetworkState[] { buildWifi() };
979ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme        when(mConnManager.getAllNetworkState()).thenReturn(state);
98021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey
981ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme        mPolicyListener.expect().onMeteredIfacesChanged(any());
982f851d6dd2a15b74f63c85403afad0ed747f7311cErik Kline        mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION));
983ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme        mPolicyListener.waitAndVerify().onMeteredIfacesChanged(any());
98421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey
98521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        // now change cycle to be on 15th, and test in early march, to verify we
98621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        // pick cycle day in previous month.
987ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme        when(mConnManager.getAllNetworkState()).thenReturn(state);
98821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey
98921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        // pretend that 512 bytes total have happened
9908e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey        stats = new NetworkStats(getElapsedRealtime(), 1)
991b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey                .addIfaceValues(TEST_IFACE, 256L, 2L, 256L, 2L);
99253313d7e8153982f842910118371e1dc061248cdJeff Sharkey        when(mStatsService.getNetworkTotalBytes(sTemplateWifi, CYCLE_START, CYCLE_END))
993ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme                .thenReturn(stats.getTotalBytes());
99421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey
995ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme        mPolicyListener.expect().onMeteredIfacesChanged(any());
996163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey        setNetworkPolicies(new NetworkPolicy(
9979bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey                sTemplateWifi, CYCLE_DAY, TIMEZONE_UTC, 1 * MB_IN_BYTES, 2 * MB_IN_BYTES, false));
998ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme        mPolicyListener.waitAndVerify().onMeteredIfacesChanged(eq(new String[]{TEST_IFACE}));
99921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey
1000bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey        verify(mNetworkManager, atLeastOnce()).setInterfaceQuota(TEST_IFACE,
1001bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey                (2 * MB_IN_BYTES) - 512);
1002ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme    }
10034414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey
10049f27e7ad34054e7e1d742845983a355eea63f205Felipe Leme    @Test
1005bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey    public void testNotificationWarningLimitSnooze() throws Exception {
1006bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey        // Create a place to store fake usage
1007bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey        final NetworkStatsHistory history = new NetworkStatsHistory(TimeUnit.HOURS.toMillis(1));
1008e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey        final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 0);
1009bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey        when(mStatsService.getNetworkTotalBytes(any(), anyLong(), anyLong()))
1010bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey                .thenAnswer(new Answer<Long>() {
1011bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey                    @Override
1012bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey                    public Long answer(InvocationOnMock invocation) throws Throwable {
1013bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey                        final NetworkStatsHistory.Entry entry = history.getValues(
1014bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey                                invocation.getArgument(1), invocation.getArgument(2), null);
1015bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey                        return entry.rxBytes + entry.txBytes;
1016bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey                    }
1017bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey                });
1018e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey        when(mStatsService.getNetworkUidBytes(any(), anyLong(), anyLong()))
1019e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey                .thenAnswer(new Answer<NetworkStats>() {
1020e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey                    @Override
1021e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey                    public NetworkStats answer(InvocationOnMock invocation) throws Throwable {
1022e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey                        return stats;
1023e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey                    }
1024e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey                });
102541ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey
1026bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey        // Get active mobile network in place
1027bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey        expectMobileDefaults();
1028bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey        mService.updateNetworks();
102941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey
1030bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey        // Define simple data plan
1031ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN        final SubscriptionPlan plan = buildMonthlyDataPlan(
1032ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN                ZonedDateTime.parse("2015-11-01T00:00:00.00Z"), DataUnit.MEGABYTES.toBytes(1800));
1033bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey        mService.setSubscriptionPlans(TEST_SUB_ID, new SubscriptionPlan[] { plan },
1034bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey                mServiceContext.getOpPackageName());
10358e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey
1036bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey        // We're 20% through the month (6 days)
1037bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey        final long start = parseTime("2015-11-01T00:00Z");
1038bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey        final long end = parseTime("2015-11-07T00:00Z");
1039bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey        setCurrentTimeMillis(end);
104041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey
1041bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey        // Normal usage means no notification
104241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        {
1043e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey            history.clear();
1044bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey            history.recordData(start, end,
1045bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey                    new NetworkStats.Entry(DataUnit.MEGABYTES.toBytes(360), 0L, 0L, 0L, 0));
104641ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey
1047bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey            reset(mTelephonyManager, mNetworkManager, mNotifManager);
1048bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey            expectMobileDefaults();
104941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey
1050bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey            mService.updateNetworks();
1051ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme
1052bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey            verify(mTelephonyManager, atLeastOnce()).setPolicyDataEnabled(true, TEST_SUB_ID);
1053bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey            verify(mNetworkManager, atLeastOnce()).setInterfaceQuota(TEST_IFACE,
1054bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey                    DataUnit.MEGABYTES.toBytes(1800 - 360));
1055bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey            verify(mNotifManager, never()).notifyAsUser(any(), anyInt(), any(), any());
105641ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        }
105741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey
1058bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey        // Push over warning
105941ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        {
1060e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey            history.clear();
1061bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey            history.recordData(start, end,
1062bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey                    new NetworkStats.Entry(DataUnit.MEGABYTES.toBytes(1799), 0L, 0L, 0L, 0));
106341ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey
1064bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey            reset(mTelephonyManager, mNetworkManager, mNotifManager);
1065bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey            expectMobileDefaults();
1066ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme
1067bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey            mService.updateNetworks();
1068ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme
1069bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey            verify(mTelephonyManager, atLeastOnce()).setPolicyDataEnabled(true, TEST_SUB_ID);
1070bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey            verify(mNetworkManager, atLeastOnce()).setInterfaceQuota(TEST_IFACE,
1071bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey                    DataUnit.MEGABYTES.toBytes(1800 - 1799));
1072bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey            verify(mNotifManager, atLeastOnce()).notifyAsUser(any(), eq(TYPE_WARNING),
1073bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey                    isA(Notification.class), eq(UserHandle.ALL));
107441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        }
107541ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey
1076bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey        // Push over limit
107741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        {
1078e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey            history.clear();
1079bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey            history.recordData(start, end,
1080bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey                    new NetworkStats.Entry(DataUnit.MEGABYTES.toBytes(1810), 0L, 0L, 0L, 0));
108141ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey
1082bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey            reset(mTelephonyManager, mNetworkManager, mNotifManager);
1083bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey            expectMobileDefaults();
1084ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme
1085bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey            mService.updateNetworks();
108641ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey
1087bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey            verify(mTelephonyManager, atLeastOnce()).setPolicyDataEnabled(false, TEST_SUB_ID);
1088bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey            verify(mNetworkManager, atLeastOnce()).setInterfaceQuota(TEST_IFACE, 1);
1089bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey            verify(mNotifManager, atLeastOnce()).notifyAsUser(any(), eq(TYPE_LIMIT),
1090bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey                    isA(Notification.class), eq(UserHandle.ALL));
1091bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey        }
109241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey
1093bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey        // Snooze limit
109441ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        {
1095bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey            reset(mTelephonyManager, mNetworkManager, mNotifManager);
1096bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey            expectMobileDefaults();
109741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey
1098bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey            mService.snoozeLimit(NetworkTemplate.buildTemplateMobileAll(TEST_IMSI));
1099bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey            mService.updateNetworks();
1100ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme
1101bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey            verify(mTelephonyManager, atLeastOnce()).setPolicyDataEnabled(true, TEST_SUB_ID);
1102bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey            verify(mNetworkManager, atLeastOnce()).setInterfaceQuota(TEST_IFACE,
1103bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey                    Long.MAX_VALUE);
1104bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey            verify(mNotifManager, atLeastOnce()).notifyAsUser(any(), eq(TYPE_LIMIT_SNOOZED),
1105bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey                    isA(Notification.class), eq(UserHandle.ALL));
110641ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey        }
110741ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey    }
110841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey
11099f27e7ad34054e7e1d742845983a355eea63f205Felipe Leme    @Test
1110bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey    public void testNotificationRapid() throws Exception {
11112e4714575ff7aac65a0e107cbf2dd03fa3affe95Jeff Sharkey        // Create a place to store fake usage
11122e4714575ff7aac65a0e107cbf2dd03fa3affe95Jeff Sharkey        final NetworkStatsHistory history = new NetworkStatsHistory(TimeUnit.HOURS.toMillis(1));
1113e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey        final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 0);
11142e4714575ff7aac65a0e107cbf2dd03fa3affe95Jeff Sharkey        when(mStatsService.getNetworkTotalBytes(any(), anyLong(), anyLong()))
11152e4714575ff7aac65a0e107cbf2dd03fa3affe95Jeff Sharkey                .thenAnswer(new Answer<Long>() {
11162e4714575ff7aac65a0e107cbf2dd03fa3affe95Jeff Sharkey                    @Override
11172e4714575ff7aac65a0e107cbf2dd03fa3affe95Jeff Sharkey                    public Long answer(InvocationOnMock invocation) throws Throwable {
11182e4714575ff7aac65a0e107cbf2dd03fa3affe95Jeff Sharkey                        final NetworkStatsHistory.Entry entry = history.getValues(
11192e4714575ff7aac65a0e107cbf2dd03fa3affe95Jeff Sharkey                                invocation.getArgument(1), invocation.getArgument(2), null);
11202e4714575ff7aac65a0e107cbf2dd03fa3affe95Jeff Sharkey                        return entry.rxBytes + entry.txBytes;
11212e4714575ff7aac65a0e107cbf2dd03fa3affe95Jeff Sharkey                    }
11222e4714575ff7aac65a0e107cbf2dd03fa3affe95Jeff Sharkey                });
1123e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey        when(mStatsService.getNetworkUidBytes(any(), anyLong(), anyLong()))
1124e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey                .thenAnswer(new Answer<NetworkStats>() {
1125e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey                    @Override
1126e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey                    public NetworkStats answer(InvocationOnMock invocation) throws Throwable {
1127e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey                        return stats;
1128e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey                    }
1129e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey                });
11302e4714575ff7aac65a0e107cbf2dd03fa3affe95Jeff Sharkey
1131bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey        // Get active mobile network in place
1132bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey        expectMobileDefaults();
1133bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey        mService.updateNetworks();
1134bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey
11352e4714575ff7aac65a0e107cbf2dd03fa3affe95Jeff Sharkey        // Define simple data plan which gives us effectively 60MB/day
1136ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN        final SubscriptionPlan plan = buildMonthlyDataPlan(
1137ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN                ZonedDateTime.parse("2015-11-01T00:00:00.00Z"), DataUnit.MEGABYTES.toBytes(1800));
1138bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey        mService.setSubscriptionPlans(TEST_SUB_ID, new SubscriptionPlan[] { plan },
11392e4714575ff7aac65a0e107cbf2dd03fa3affe95Jeff Sharkey                mServiceContext.getOpPackageName());
11402e4714575ff7aac65a0e107cbf2dd03fa3affe95Jeff Sharkey
11412e4714575ff7aac65a0e107cbf2dd03fa3affe95Jeff Sharkey        // We're 20% through the month (6 days)
11422e4714575ff7aac65a0e107cbf2dd03fa3affe95Jeff Sharkey        final long start = parseTime("2015-11-01T00:00Z");
11432e4714575ff7aac65a0e107cbf2dd03fa3affe95Jeff Sharkey        final long end = parseTime("2015-11-07T00:00Z");
11442e4714575ff7aac65a0e107cbf2dd03fa3affe95Jeff Sharkey        setCurrentTimeMillis(end);
11452e4714575ff7aac65a0e107cbf2dd03fa3affe95Jeff Sharkey
1146bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey        // Using 20% data in 20% time is normal
11472e4714575ff7aac65a0e107cbf2dd03fa3affe95Jeff Sharkey        {
1148e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey            history.clear();
11492e4714575ff7aac65a0e107cbf2dd03fa3affe95Jeff Sharkey            history.recordData(start, end,
11502e4714575ff7aac65a0e107cbf2dd03fa3affe95Jeff Sharkey                    new NetworkStats.Entry(DataUnit.MEGABYTES.toBytes(360), 0L, 0L, 0L, 0));
11512e4714575ff7aac65a0e107cbf2dd03fa3affe95Jeff Sharkey
11522e4714575ff7aac65a0e107cbf2dd03fa3affe95Jeff Sharkey            reset(mNotifManager);
1153bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey            mService.updateNetworks();
1154bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey            verify(mNotifManager, never()).notifyAsUser(any(), anyInt(), any(), any());
11552e4714575ff7aac65a0e107cbf2dd03fa3affe95Jeff Sharkey        }
11562e4714575ff7aac65a0e107cbf2dd03fa3affe95Jeff Sharkey
1157e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey        // Using 80% data in 20% time is alarming; but spread equally among
1158e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey        // three UIDs means we get generic alert
11592e4714575ff7aac65a0e107cbf2dd03fa3affe95Jeff Sharkey        {
1160e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey            history.clear();
11612e4714575ff7aac65a0e107cbf2dd03fa3affe95Jeff Sharkey            history.recordData(start, end,
11622e4714575ff7aac65a0e107cbf2dd03fa3affe95Jeff Sharkey                    new NetworkStats.Entry(DataUnit.MEGABYTES.toBytes(1440), 0L, 0L, 0L, 0));
1163e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey            stats.clear();
1164e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey            stats.addValues(IFACE_ALL, UID_A, SET_ALL, TAG_ALL,
1165e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey                    DataUnit.MEGABYTES.toBytes(480), 0, 0, 0, 0);
1166e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey            stats.addValues(IFACE_ALL, UID_B, SET_ALL, TAG_ALL,
1167e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey                    DataUnit.MEGABYTES.toBytes(480), 0, 0, 0, 0);
1168e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey            stats.addValues(IFACE_ALL, UID_C, SET_ALL, TAG_ALL,
1169e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey                    DataUnit.MEGABYTES.toBytes(480), 0, 0, 0, 0);
11702e4714575ff7aac65a0e107cbf2dd03fa3affe95Jeff Sharkey
11712e4714575ff7aac65a0e107cbf2dd03fa3affe95Jeff Sharkey            reset(mNotifManager);
1172bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey            mService.updateNetworks();
1173e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey
1174e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey            final ArgumentCaptor<Notification> notif = ArgumentCaptor.forClass(Notification.class);
1175bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey            verify(mNotifManager, atLeastOnce()).notifyAsUser(any(), eq(TYPE_RAPID),
1176e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey                    notif.capture(), eq(UserHandle.ALL));
1177e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey
1178e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey            final String text = notif.getValue().extras.getCharSequence(Notification.EXTRA_TEXT)
1179e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey                    .toString();
1180e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey            assertFalse(text.contains(PKG_NAME_A));
1181e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey            assertFalse(text.contains(PKG_NAME_B));
1182e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey            assertFalse(text.contains(PKG_NAME_C));
1183e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey        }
1184e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey
1185e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey        // Using 80% data in 20% time is alarming; but mostly done by one UID
1186e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey        // means we get specific alert
1187e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey        {
1188e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey            history.clear();
1189e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey            history.recordData(start, end,
1190e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey                    new NetworkStats.Entry(DataUnit.MEGABYTES.toBytes(1440), 0L, 0L, 0L, 0));
1191e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey            stats.clear();
1192e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey            stats.addValues(IFACE_ALL, UID_A, SET_ALL, TAG_ALL,
1193e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey                    DataUnit.MEGABYTES.toBytes(960), 0, 0, 0, 0);
1194e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey            stats.addValues(IFACE_ALL, UID_B, SET_ALL, TAG_ALL,
1195e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey                    DataUnit.MEGABYTES.toBytes(480), 0, 0, 0, 0);
1196e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey
1197e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey            reset(mNotifManager);
1198e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey            mService.updateNetworks();
1199e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey
1200e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey            final ArgumentCaptor<Notification> notif = ArgumentCaptor.forClass(Notification.class);
1201e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey            verify(mNotifManager, atLeastOnce()).notifyAsUser(any(), eq(TYPE_RAPID),
1202e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey                    notif.capture(), eq(UserHandle.ALL));
1203e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey
1204e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey            final String text = notif.getValue().extras.getCharSequence(Notification.EXTRA_TEXT)
1205e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey                    .toString();
1206e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey            assertTrue(text.contains(PKG_NAME_A));
1207e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey            assertFalse(text.contains(PKG_NAME_B));
1208e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey            assertFalse(text.contains(PKG_NAME_C));
12092e4714575ff7aac65a0e107cbf2dd03fa3affe95Jeff Sharkey        }
12102e4714575ff7aac65a0e107cbf2dd03fa3affe95Jeff Sharkey    }
12112e4714575ff7aac65a0e107cbf2dd03fa3affe95Jeff Sharkey
12122e4714575ff7aac65a0e107cbf2dd03fa3affe95Jeff Sharkey    @Test
1213f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey    public void testMeteredNetworkWithoutLimit() throws Exception {
1214f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey        NetworkState[] state = null;
1215f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey        NetworkStats stats = null;
1216f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey
1217f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey        final long TIME_FEB_15 = 1171497600000L;
1218f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey        final long TIME_MAR_10 = 1173484800000L;
1219f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey        final int CYCLE_DAY = 15;
1220f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey
1221f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey        setCurrentTimeMillis(TIME_MAR_10);
1222f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey
1223f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey        // bring up wifi network with metered policy
1224f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey        state = new NetworkState[] { buildWifi() };
1225f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey        stats = new NetworkStats(getElapsedRealtime(), 1)
1226f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey                .addIfaceValues(TEST_IFACE, 0L, 0L, 0L, 0L);
1227f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey
1228f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey        {
1229ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme            when(mConnManager.getAllNetworkState()).thenReturn(state);
1230ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme            when(mStatsService.getNetworkTotalBytes(sTemplateWifi, TIME_FEB_15,
1231ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme                    currentTimeMillis())).thenReturn(stats.getTotalBytes());
1232f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey
1233ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme            mPolicyListener.expect().onMeteredIfacesChanged(any());
12349bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey            setNetworkPolicies(new NetworkPolicy(
12359bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey                    sTemplateWifi, CYCLE_DAY, TIMEZONE_UTC, WARNING_DISABLED, LIMIT_DISABLED,
12369bf3150cfae03421c9dd237b46657714859d871cJeff Sharkey                    true));
1237ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme            mPolicyListener.waitAndVerify().onMeteredIfacesChanged(eq(new String[]{TEST_IFACE}));
1238ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme
1239bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey            verify(mNetworkManager, atLeastOnce()).setInterfaceQuota(TEST_IFACE,
1240bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey                    Long.MAX_VALUE);
1241f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey        }
1242f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey    }
1243f60d0afd1ef08a24121d015bb016df05265b6d07Jeff Sharkey
1244e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shanka    @Test
1245e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shanka    public void testOnUidStateChanged_notifyAMS() throws Exception {
1246e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shanka        final long procStateSeq = 222;
1247ed25ce6d598d7ed14f9b9859cdd2219bcc907f4cSudheer Shanka        callOnUidStateChanged(UID_A, ActivityManager.PROCESS_STATE_SERVICE, procStateSeq);
1248e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shanka        verify(mActivityManagerInternal).notifyNetworkPolicyRulesUpdated(UID_A, procStateSeq);
1249e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shanka    }
1250e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shanka
1251ed25ce6d598d7ed14f9b9859cdd2219bcc907f4cSudheer Shanka    private void callOnUidStateChanged(int uid, int procState, long procStateSeq)
1252ed25ce6d598d7ed14f9b9859cdd2219bcc907f4cSudheer Shanka            throws Exception {
1253ed25ce6d598d7ed14f9b9859cdd2219bcc907f4cSudheer Shanka        mUidObserver.onUidStateChanged(uid, procState, procStateSeq);
1254ed25ce6d598d7ed14f9b9859cdd2219bcc907f4cSudheer Shanka        final CountDownLatch latch = new CountDownLatch(1);
1255ed25ce6d598d7ed14f9b9859cdd2219bcc907f4cSudheer Shanka        mService.mUidEventHandler.post(() -> {
1256ed25ce6d598d7ed14f9b9859cdd2219bcc907f4cSudheer Shanka            latch.countDown();
1257ed25ce6d598d7ed14f9b9859cdd2219bcc907f4cSudheer Shanka        });
1258ed25ce6d598d7ed14f9b9859cdd2219bcc907f4cSudheer Shanka        latch.await(2, TimeUnit.SECONDS);
1259ed25ce6d598d7ed14f9b9859cdd2219bcc907f4cSudheer Shanka    }
1260ed25ce6d598d7ed14f9b9859cdd2219bcc907f4cSudheer Shanka
12616ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi    private void assertCycleDayAsExpected(PersistableBundle config, int carrierCycleDay,
12626ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi            boolean expectValid) {
12636ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        config.putInt(KEY_MONTHLY_DATA_CYCLE_DAY_INT, carrierCycleDay);
12646ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        int actualCycleDay = mService.getCycleDayFromCarrierConfig(config,
12656ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi                INVALID_CARRIER_CONFIG_VALUE);
12666ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        if (expectValid) {
12676ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi            assertEquals(carrierCycleDay, actualCycleDay);
12686ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        } else {
12696ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi            // INVALID_CARRIER_CONFIG_VALUE is returned for invalid values
12706ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi            assertEquals(INVALID_CARRIER_CONFIG_VALUE, actualCycleDay);
12716ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        }
12726ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi    }
12736ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi
12746ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi    @Test
12756ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi    public void testGetCycleDayFromCarrierConfig() {
12766ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        PersistableBundle config = CarrierConfigManager.getDefaultConfig();
12776ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        final Calendar cal = Calendar.getInstance();
12786ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        int actualCycleDay;
12796ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi
12806ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        config.putInt(KEY_MONTHLY_DATA_CYCLE_DAY_INT, DATA_CYCLE_USE_PLATFORM_DEFAULT);
12816ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        actualCycleDay = mService.getCycleDayFromCarrierConfig(config, DEFAULT_CYCLE_DAY);
12826ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        assertEquals(DEFAULT_CYCLE_DAY, actualCycleDay);
12836ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi
12846ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        // null config returns a default value
12856ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        actualCycleDay = mService.getCycleDayFromCarrierConfig(null, DEFAULT_CYCLE_DAY);
12866ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        assertEquals(DEFAULT_CYCLE_DAY, actualCycleDay);
12876ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi
12886ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        // Sane, non-default values
12896ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        assertCycleDayAsExpected(config, 1, true);
12906ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        assertCycleDayAsExpected(config, cal.getMaximum(Calendar.DAY_OF_MONTH), true);
12916ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        assertCycleDayAsExpected(config, cal.getMinimum(Calendar.DAY_OF_MONTH), true);
12926ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi
12936ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        // Invalid values
12946ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        assertCycleDayAsExpected(config, 0, false);
12956ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        assertCycleDayAsExpected(config, DATA_CYCLE_THRESHOLD_DISABLED, false);
12966ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        assertCycleDayAsExpected(config, cal.getMaximum(Calendar.DAY_OF_MONTH) + 1, false);
12976ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        assertCycleDayAsExpected(config, cal.getMinimum(Calendar.DAY_OF_MONTH) - 5, false);
12986ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi    }
12996ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi
13006ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi    private void assertWarningBytesAsExpected(PersistableBundle config, long carrierWarningBytes,
13016ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi            long expected) {
13026ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        config.putLong(KEY_DATA_WARNING_THRESHOLD_BYTES_LONG, carrierWarningBytes);
13036ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        long actualWarning = mService.getWarningBytesFromCarrierConfig(config,
13046ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi                INVALID_CARRIER_CONFIG_VALUE);
13056ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        assertEquals(expected, actualWarning);
13066ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi    }
13076ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi
13086ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi    @Test
13096ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi    public void testGetWarningBytesFromCarrierConfig() {
13106ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        PersistableBundle config = CarrierConfigManager.getDefaultConfig();
13116ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        long actualWarningBytes;
13126ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi
13136ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        assertWarningBytesAsExpected(config, DATA_CYCLE_USE_PLATFORM_DEFAULT,
13146ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi                mDefaultWarningBytes);
13156ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        assertWarningBytesAsExpected(config, DATA_CYCLE_THRESHOLD_DISABLED, WARNING_DISABLED);
13166ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        assertWarningBytesAsExpected(config, 0, 0);
13176ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        // not a valid value
13186ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        assertWarningBytesAsExpected(config, -1000, INVALID_CARRIER_CONFIG_VALUE);
13196ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi
13206ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        // null config returns a default value
13216ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        actualWarningBytes = mService.getWarningBytesFromCarrierConfig(null, mDefaultWarningBytes);
13226ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        assertEquals(mDefaultWarningBytes, actualWarningBytes);
13236ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi    }
13246ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi
13256ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi    private void assertLimitBytesAsExpected(PersistableBundle config,  long carrierWarningBytes,
13266ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi            long expected) {
13276ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        config.putLong(KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG, carrierWarningBytes);
13286ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        long actualWarning = mService.getLimitBytesFromCarrierConfig(config,
13296ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi                INVALID_CARRIER_CONFIG_VALUE);
13306ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        assertEquals(expected, actualWarning);
13316ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi    }
13326ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi
13336ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi    @Test
13346ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi    public void testGetLimitBytesFromCarrierConfig() {
13356ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        PersistableBundle config = CarrierConfigManager.getDefaultConfig();
13366ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        long actualLimitBytes;
13376ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi
13386ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        assertLimitBytesAsExpected(config, DATA_CYCLE_USE_PLATFORM_DEFAULT,
13396ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi                mDefaultLimitBytes);
13406ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        assertLimitBytesAsExpected(config, DATA_CYCLE_THRESHOLD_DISABLED, LIMIT_DISABLED);
13416ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        assertLimitBytesAsExpected(config, 0, 0);
13426ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        // not a valid value
13436ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        assertLimitBytesAsExpected(config, -1000, INVALID_CARRIER_CONFIG_VALUE);
13446ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi
13456ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        // null config returns a default value
13466ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        actualLimitBytes = mService.getWarningBytesFromCarrierConfig(null, mDefaultLimitBytes);
13476ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        assertEquals(mDefaultLimitBytes, actualLimitBytes);
13486ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi    }
13496ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi
13506ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi    private PersistableBundle setupUpdateMobilePolicyCycleTests() throws RemoteException {
13516ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        when(mConnManager.getAllNetworkState()).thenReturn(new NetworkState[0]);
13526ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        when(mSubscriptionManager.getActiveSubscriptionIdList()).thenReturn(new int[]{FAKE_SUB_ID});
13536ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        when(mTelephonyManager.getSubscriberId(FAKE_SUB_ID)).thenReturn(FAKE_SUBSCRIBER_ID);
13546ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        PersistableBundle bundle = CarrierConfigManager.getDefaultConfig();
13556ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        when(mCarrierConfigManager.getConfigForSubId(FAKE_SUB_ID)).thenReturn(bundle);
13566ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        setNetworkPolicies(buildDefaultFakeMobilePolicy());
13576ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        return bundle;
13586ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi    }
13596ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi
13606ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi    @Test
13616ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi    public void testUpdateMobilePolicyCycleWithNullConfig() throws RemoteException {
13626ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        when(mConnManager.getAllNetworkState()).thenReturn(new NetworkState[0]);
13636ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        when(mSubscriptionManager.getActiveSubscriptionIdList()).thenReturn(new int[]{FAKE_SUB_ID});
13646ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        when(mTelephonyManager.getSubscriberId(FAKE_SUB_ID)).thenReturn(FAKE_SUBSCRIBER_ID);
13656ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        when(mCarrierConfigManager.getConfigForSubId(FAKE_SUB_ID)).thenReturn(null);
13666ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        setNetworkPolicies(buildDefaultFakeMobilePolicy());
13676ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        // smoke test to make sure no errors are raised
13686ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        mServiceContext.sendBroadcast(
13696ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi                new Intent(ACTION_CARRIER_CONFIG_CHANGED)
13706ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi                        .putExtra(PhoneConstants.SUBSCRIPTION_KEY, FAKE_SUB_ID)
13716ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        );
13726ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        assertNetworkPolicyEquals(DEFAULT_CYCLE_DAY, mDefaultWarningBytes, mDefaultLimitBytes,
13736ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi                true);
13746ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi    }
13756ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi
13766ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi    @Test
13776ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi    public void testUpdateMobilePolicyCycleWithInvalidConfig() throws RemoteException {
13786ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        PersistableBundle bundle = setupUpdateMobilePolicyCycleTests();
13796ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        // Test with an invalid CarrierConfig, there should be no changes or crashes.
13806ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        bundle.putInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT, -100);
13816ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        bundle.putLong(CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG, -100);
13826ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        bundle.putLong(CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG, -100);
13836ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        mServiceContext.sendBroadcast(
13846ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi                new Intent(ACTION_CARRIER_CONFIG_CHANGED)
13856ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi                        .putExtra(PhoneConstants.SUBSCRIPTION_KEY, FAKE_SUB_ID)
13866ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        );
13876ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi
13886ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        assertNetworkPolicyEquals(DEFAULT_CYCLE_DAY, mDefaultWarningBytes, mDefaultLimitBytes,
13896ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi                true);
13906ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi    }
13916ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi
13926ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi    @Test
13936ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi    public void testUpdateMobilePolicyCycleWithDefaultConfig() throws RemoteException {
13946ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        PersistableBundle bundle = setupUpdateMobilePolicyCycleTests();
13956ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        // Test that we respect the platform values when told to
13966ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        bundle.putInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT,
13976ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi                DATA_CYCLE_USE_PLATFORM_DEFAULT);
13986ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        bundle.putLong(CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG,
13996ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi                DATA_CYCLE_USE_PLATFORM_DEFAULT);
14006ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        bundle.putLong(CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG,
14016ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi                DATA_CYCLE_USE_PLATFORM_DEFAULT);
14026ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        mServiceContext.sendBroadcast(
14036ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi                new Intent(ACTION_CARRIER_CONFIG_CHANGED)
14046ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi                        .putExtra(PhoneConstants.SUBSCRIPTION_KEY, FAKE_SUB_ID)
14056ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        );
14066ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi
14076ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        assertNetworkPolicyEquals(DEFAULT_CYCLE_DAY, mDefaultWarningBytes, mDefaultLimitBytes,
14086ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi                true);
14096ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi    }
14106ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi
14116ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi    @Test
14126ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi    public void testUpdateMobilePolicyCycleWithUserOverrides() throws RemoteException {
14136ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        PersistableBundle bundle = setupUpdateMobilePolicyCycleTests();
14146ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi
14156ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        // inferred = false implies that a user manually modified this policy.
14166ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        NetworkPolicy policy = buildDefaultFakeMobilePolicy();
14176ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        policy.inferred = false;
14186ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        setNetworkPolicies(policy);
14196ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi
14206ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        bundle.putInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT, 31);
14216ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        bundle.putLong(CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG, 9999);
14226ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        bundle.putLong(CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG,
14236ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi                DATA_CYCLE_THRESHOLD_DISABLED);
14246ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        mServiceContext.sendBroadcast(
14256ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi                new Intent(ACTION_CARRIER_CONFIG_CHANGED)
14266ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi                        .putExtra(PhoneConstants.SUBSCRIPTION_KEY, FAKE_SUB_ID)
14276ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        );
14286ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi
14296ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        // The policy still shouldn't change, because we don't want to overwrite user settings.
14306ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        assertNetworkPolicyEquals(DEFAULT_CYCLE_DAY, mDefaultWarningBytes, mDefaultLimitBytes,
14316ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi                false);
14326ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi    }
14336ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi
14346ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi    @Test
14356ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi    public void testUpdateMobilePolicyCycleUpdatesDataCycle() throws RemoteException {
14366ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        PersistableBundle bundle = setupUpdateMobilePolicyCycleTests();
14376ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi
14386ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        bundle.putInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT, 31);
14396ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        bundle.putLong(CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG, 9999);
14406ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        bundle.putLong(CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG, 9999);
14416ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        mServiceContext.sendBroadcast(
14426ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi                new Intent(ACTION_CARRIER_CONFIG_CHANGED)
14436ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi                        .putExtra(PhoneConstants.SUBSCRIPTION_KEY, FAKE_SUB_ID)
14446ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        );
14456ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi
14466ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        assertNetworkPolicyEquals(31, 9999, 9999, true);
14476ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi    }
14486ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi
14496ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi    @Test
14506ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi    public void testUpdateMobilePolicyCycleDisableThresholds() throws RemoteException {
14516ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        PersistableBundle bundle = setupUpdateMobilePolicyCycleTests();
14526ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi
14536ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        bundle.putInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT, 31);
14546ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        bundle.putLong(CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG,
14556ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi                DATA_CYCLE_THRESHOLD_DISABLED);
14566ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        bundle.putLong(CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG,
14576ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi                DATA_CYCLE_THRESHOLD_DISABLED);
14586ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        mServiceContext.sendBroadcast(
14596ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi                new Intent(ACTION_CARRIER_CONFIG_CHANGED)
14606ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi                        .putExtra(PhoneConstants.SUBSCRIPTION_KEY, FAKE_SUB_ID)
14616ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        );
14626ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi
14636ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        assertNetworkPolicyEquals(31, WARNING_DISABLED, LIMIT_DISABLED, true);
14646ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi    }
14656ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi
14666ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi    @Test
14676ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi    public void testUpdateMobilePolicyCycleRevertsToDefault() throws RemoteException {
14686ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        PersistableBundle bundle = setupUpdateMobilePolicyCycleTests();
14696ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi
14706ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        bundle.putInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT, 31);
14716ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        bundle.putLong(CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG,
14726ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi                DATA_CYCLE_THRESHOLD_DISABLED);
14736ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        bundle.putLong(CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG,
14746ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi                DATA_CYCLE_THRESHOLD_DISABLED);
14756ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        mServiceContext.sendBroadcast(
14766ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi                new Intent(ACTION_CARRIER_CONFIG_CHANGED)
14776ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi                        .putExtra(PhoneConstants.SUBSCRIPTION_KEY, FAKE_SUB_ID)
14786ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        );
14796ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        assertNetworkPolicyEquals(31, WARNING_DISABLED, LIMIT_DISABLED, true);
14806ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi
14816ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        // If the user switches carriers to one that doesn't use a CarrierConfig, we should revert
14826ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        // to the default data limit and warning. The cycle date doesn't need to revert as it's
14836ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        // arbitrary anyways.
14846ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        bundle.putInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT,
14856ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi                DATA_CYCLE_USE_PLATFORM_DEFAULT);
14866ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        bundle.putLong(CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG,
14876ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi                DATA_CYCLE_USE_PLATFORM_DEFAULT);
14886ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        bundle.putLong(CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG,
14896ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi                DATA_CYCLE_USE_PLATFORM_DEFAULT);
14906ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        mServiceContext.sendBroadcast(
14916ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi                new Intent(ACTION_CARRIER_CONFIG_CHANGED)
14926ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi                        .putExtra(PhoneConstants.SUBSCRIPTION_KEY, FAKE_SUB_ID)
14936ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        );
14946ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi
14956ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        assertNetworkPolicyEquals(31, mDefaultWarningBytes, mDefaultLimitBytes,
14966ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi                true);
14976ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi    }
14986ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi
149936b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey    @Test
150036b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey    public void testOpportunisticQuota() throws Exception {
150136b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey        final Network net = new Network(TEST_NET_ID);
150236b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey        final NetworkPolicyManagerInternal internal = LocalServices
150336b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey                .getService(NetworkPolicyManagerInternal.class);
150436b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey
150536b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey        // Create a place to store fake usage
150636b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey        final NetworkStatsHistory history = new NetworkStatsHistory(TimeUnit.HOURS.toMillis(1));
150736b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey        final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 0);
150836b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey        when(mStatsService.getNetworkTotalBytes(any(), anyLong(), anyLong()))
1509ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN                .thenAnswer(invocation -> {
1510ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN                    final NetworkStatsHistory.Entry entry = history.getValues(
1511ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN                            invocation.getArgument(1), invocation.getArgument(2), null);
1512ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN                    return entry.rxBytes + entry.txBytes;
151336b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey                });
151436b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey        when(mStatsService.getNetworkUidBytes(any(), anyLong(), anyLong()))
1515ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN                .thenReturn(stats);
151636b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey
151736b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey        // Get active mobile network in place
151836b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey        expectMobileDefaults();
151936b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey        mService.updateNetworks();
152036b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey
152136b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey        // We're 20% through the month (6 days)
152236b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey        final long start = parseTime("2015-11-01T00:00Z");
152336b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey        final long end = parseTime("2015-11-07T00:00Z");
152436b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey        setCurrentTimeMillis(end);
152536b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey
152636b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey        // Get some data usage in place
152736b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey        history.clear();
152836b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey        history.recordData(start, end,
152936b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey                new NetworkStats.Entry(DataUnit.MEGABYTES.toBytes(360), 0L, 0L, 0L, 0));
153036b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey
153136b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey        // No data plan
153236b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey        {
153336b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey            reset(mTelephonyManager, mNetworkManager, mNotifManager);
153436b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey            expectMobileDefaults();
153536b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey
153636b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey            mService.updateNetworks();
153736b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey
153836b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey            // No quotas
1539ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN            assertEquals(OPPORTUNISTIC_QUOTA_UNKNOWN,
1540ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN                    internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_JOBS));
1541ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN            assertEquals(OPPORTUNISTIC_QUOTA_UNKNOWN,
1542ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN                    internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_MULTIPATH));
154336b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey        }
154436b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey
154536b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey        // Limited data plan
154636b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey        {
1547ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN            final SubscriptionPlan plan = buildMonthlyDataPlan(
1548ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN                    ZonedDateTime.parse("2015-11-01T00:00:00.00Z"),
1549ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN                    DataUnit.MEGABYTES.toBytes(1800));
1550ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN            mService.setSubscriptionPlans(TEST_SUB_ID, new SubscriptionPlan[]{plan},
155136b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey                    mServiceContext.getOpPackageName());
155236b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey
155336b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey            reset(mTelephonyManager, mNetworkManager, mNotifManager);
155436b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey            expectMobileDefaults();
155536b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey
155636b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey            mService.updateNetworks();
155736b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey
155836b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey            // We have 1440MB and 24 days left, which is 60MB/day; assuming 10%
155936b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey            // for quota split equally between two types gives 3MB.
156036b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey            assertEquals(DataUnit.MEGABYTES.toBytes(3),
156136b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey                    internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_JOBS));
156236b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey            assertEquals(DataUnit.MEGABYTES.toBytes(3),
156336b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey                    internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_MULTIPATH));
156436b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey        }
156536b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey
1566ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN        // Limited data plan, over quota
1567ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN        {
1568ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN            final SubscriptionPlan plan = buildMonthlyDataPlan(
1569ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN                    ZonedDateTime.parse("2015-11-01T00:00:00.00Z"),
1570ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN                    DataUnit.MEGABYTES.toBytes(100));
1571ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN            mService.setSubscriptionPlans(TEST_SUB_ID, new SubscriptionPlan[]{plan},
1572ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN                    mServiceContext.getOpPackageName());
1573ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN
1574ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN            reset(mTelephonyManager, mNetworkManager, mNotifManager);
1575ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN            expectMobileDefaults();
1576ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN
1577ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN            mService.updateNetworks();
1578ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN
1579ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN            assertEquals(0L, internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_JOBS));
1580ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN            assertEquals(0L, internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_MULTIPATH));
1581ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN        }
1582ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN
1583ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN        // Roaming
1584ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN        {
1585ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN            final SubscriptionPlan plan = buildMonthlyDataPlan(
1586ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN                    ZonedDateTime.parse("2015-11-01T00:00:00.00Z"), BYTES_UNLIMITED);
1587ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN            mService.setSubscriptionPlans(TEST_SUB_ID, new SubscriptionPlan[]{plan},
1588ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN                    mServiceContext.getOpPackageName());
1589ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN
1590ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN            reset(mTelephonyManager, mNetworkManager, mNotifManager);
1591ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN            expectMobileDefaults();
1592ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN            expectNetworkState(true /* roaming */);
1593ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN
1594ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN            mService.updateNetworks();
1595ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN
1596ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN            assertEquals(0L, internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_JOBS));
1597ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN            assertEquals(0L, internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_MULTIPATH));
1598ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN        }
1599ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN
160036b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey        // Unlimited data plan
160136b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey        {
1602ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN            final SubscriptionPlan plan = buildMonthlyDataPlan(
1603ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN                    ZonedDateTime.parse("2015-11-01T00:00:00.00Z"), BYTES_UNLIMITED);
1604ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN            mService.setSubscriptionPlans(TEST_SUB_ID, new SubscriptionPlan[]{plan},
160536b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey                    mServiceContext.getOpPackageName());
160636b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey
160736b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey            reset(mTelephonyManager, mNetworkManager, mNotifManager);
160836b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey            expectMobileDefaults();
160936b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey
161036b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey            mService.updateNetworks();
161136b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey
161236b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey            // 20MB/day, split equally between two types gives 10MB.
161336b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey            assertEquals(DataUnit.MEBIBYTES.toBytes(10),
161436b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey                    internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_JOBS));
161536b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey            assertEquals(DataUnit.MEBIBYTES.toBytes(10),
161636b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey                    internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_MULTIPATH));
1617ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN
1618ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN            // Capabilities change to roaming
1619ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN            final ConnectivityManager.NetworkCallback callback = mNetworkCallbackCaptor.getValue();
1620ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN            assertNotNull(callback);
1621ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN            expectNetworkState(true /* roaming */);
1622ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN            callback.onCapabilitiesChanged(
1623ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN                    new Network(TEST_NET_ID),
1624ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN                    buildNetworkCapabilities(TEST_SUB_ID, true /* roaming */));
1625ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN
1626ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN            assertEquals(0, internal.getSubscriptionOpportunisticQuota(
1627ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN                    new Network(TEST_NET_ID), NetworkPolicyManagerInternal.QUOTA_TYPE_MULTIPATH));
162836b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey        }
162936b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey    }
163036b414bc2de065ead88a384a8e877788a5db32f1Jeff Sharkey
163120b4d846edafeaacf0da2c810f511c236fdbd187Annie Meng    /**
163220b4d846edafeaacf0da2c810f511c236fdbd187Annie Meng     * Test that policy set of {null, NetworkPolicy, null} does not crash and restores the valid
163320b4d846edafeaacf0da2c810f511c236fdbd187Annie Meng     * NetworkPolicy.
163420b4d846edafeaacf0da2c810f511c236fdbd187Annie Meng     */
163520b4d846edafeaacf0da2c810f511c236fdbd187Annie Meng    @Test
163620b4d846edafeaacf0da2c810f511c236fdbd187Annie Meng    public void testSetNetworkPolicies_withNullPolicies_doesNotThrow() {
163720b4d846edafeaacf0da2c810f511c236fdbd187Annie Meng        NetworkPolicy[] policies = new NetworkPolicy[3];
163820b4d846edafeaacf0da2c810f511c236fdbd187Annie Meng        policies[1] = buildDefaultFakeMobilePolicy();
163920b4d846edafeaacf0da2c810f511c236fdbd187Annie Meng        setNetworkPolicies(policies);
164020b4d846edafeaacf0da2c810f511c236fdbd187Annie Meng
164120b4d846edafeaacf0da2c810f511c236fdbd187Annie Meng        assertNetworkPolicyEquals(DEFAULT_CYCLE_DAY, mDefaultWarningBytes, mDefaultLimitBytes,
164220b4d846edafeaacf0da2c810f511c236fdbd187Annie Meng                true);
164320b4d846edafeaacf0da2c810f511c236fdbd187Annie Meng    }
164420b4d846edafeaacf0da2c810f511c236fdbd187Annie Meng
1645ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN    private SubscriptionPlan buildMonthlyDataPlan(ZonedDateTime start, long limitBytes) {
1646ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN        return SubscriptionPlan.Builder
1647ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN                .createRecurringMonthly(start)
1648ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN                .setDataLimit(limitBytes, LIMIT_BEHAVIOR_DISABLED)
1649ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN                .build();
1650ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN    }
1651ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN
1652e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey    private ApplicationInfo buildApplicationInfo(String label) {
1653e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey        final ApplicationInfo ai = new ApplicationInfo();
1654e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey        ai.nonLocalizedLabel = label;
1655e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey        return ai;
1656e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey    }
1657e0c2995d0f16246336d4385d5ebe631a60e12e86Jeff Sharkey
1658bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey    private NetworkInfo buildNetworkInfo() {
1659bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey        final NetworkInfo ni = new NetworkInfo(ConnectivityManager.TYPE_MOBILE,
1660bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey                TelephonyManager.NETWORK_TYPE_LTE, null, null);
1661bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey        ni.setDetailedState(NetworkInfo.DetailedState.CONNECTED, null, null);
1662bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey        return ni;
1663bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey    }
1664bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey
1665bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey    private LinkProperties buildLinkProperties(String iface) {
1666bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey        final LinkProperties lp = new LinkProperties();
1667bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey        lp.setInterfaceName(iface);
1668bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey        return lp;
1669bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey    }
1670bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey
1671ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN    private NetworkCapabilities buildNetworkCapabilities(int subId, boolean roaming) {
1672bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey        final NetworkCapabilities nc = new NetworkCapabilities();
1673bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey        nc.addTransportType(TRANSPORT_CELLULAR);
1674ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN        if (!roaming) {
1675ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN            nc.addCapability(NET_CAPABILITY_NOT_ROAMING);
1676ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN        }
1677bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey        nc.setNetworkSpecifier(new StringNetworkSpecifier(String.valueOf(subId)));
1678bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey        return nc;
1679bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey    }
1680bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey
16816ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi    private NetworkPolicy buildDefaultFakeMobilePolicy() {
16826ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        NetworkPolicy p = mService.buildDefaultMobilePolicy(FAKE_SUB_ID, FAKE_SUBSCRIBER_ID);
16836ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        // set a deterministic cycle date
168417bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey        p.cycleRule = new RecurrenceRule(
168517bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey                p.cycleRule.start.withDayOfMonth(DEFAULT_CYCLE_DAY),
168617bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey                p.cycleRule.end, Period.ofMonths(1));
16876ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        return p;
16886ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi    }
16896ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi
16906ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi    private static NetworkPolicy buildFakeMobilePolicy(int cycleDay, long warningBytes,
16916ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi            long limitBytes, boolean inferred){
16926ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        final NetworkTemplate template = buildTemplateMobileAll(FAKE_SUBSCRIBER_ID);
1693ed25ce6d598d7ed14f9b9859cdd2219bcc907f4cSudheer Shanka        return new NetworkPolicy(template, cycleDay, new Time().timezone, warningBytes,
16946ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi                limitBytes, SNOOZE_NEVER, SNOOZE_NEVER, true, inferred);
16956ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi    }
16966ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi
16976ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi    private void assertNetworkPolicyEquals(int expectedCycleDay, long expectedWarningBytes,
16986ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi            long expectedLimitBytes, boolean expectedInferred) {
16996ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        NetworkPolicy[] policies = mService.getNetworkPolicies(
17006ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi                mServiceContext.getOpPackageName());
17016ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        assertEquals("Unexpected number of network policies", 1, policies.length);
17026ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        NetworkPolicy actualPolicy = policies[0];
17036ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        NetworkPolicy expectedPolicy = buildFakeMobilePolicy(expectedCycleDay, expectedWarningBytes,
17046ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi                expectedLimitBytes, expectedInferred);
17056ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi        assertEquals(expectedPolicy, actualPolicy);
17066ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi    }
17076ce48e25e510aed187c8b2a84377e0676449767aAmmar Aijazi
170821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey    private static long parseTime(String time) {
170953313d7e8153982f842910118371e1dc061248cdJeff Sharkey        return ZonedDateTime.parse(time).toInstant().toEpochMilli();
171021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey    }
171121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey
1712af11d4859582a9736aa204562f0beac5a7d60934Jeff Sharkey    private void setNetworkPolicies(NetworkPolicy... policies) {
1713af11d4859582a9736aa204562f0beac5a7d60934Jeff Sharkey        mService.setNetworkPolicies(policies);
1714af11d4859582a9736aa204562f0beac5a7d60934Jeff Sharkey    }
1715af11d4859582a9736aa204562f0beac5a7d60934Jeff Sharkey
171621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey    private static NetworkState buildWifi() {
171721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        final NetworkInfo info = new NetworkInfo(TYPE_WIFI, 0, null, null);
171821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        info.setDetailedState(DetailedState.CONNECTED, null, null);
171921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        final LinkProperties prop = new LinkProperties();
172021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        prop.setInterfaceName(TEST_IFACE);
1721a1c92b7e8d534758d49c1808181aaa62f15357e3Stephen Chen        final NetworkCapabilities networkCapabilities = new NetworkCapabilities();
1722a1c92b7e8d534758d49c1808181aaa62f15357e3Stephen Chen        return new NetworkState(info, prop, networkCapabilities, null, null, TEST_SSID);
172321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey    }
172421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey
17253d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    private void expectHasInternetPermission(int uid, boolean hasIt) throws Exception {
17263d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        when(mIpm.checkUidPermission(Manifest.permission.INTERNET, uid)).thenReturn(
17273d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme                hasIt ? PackageManager.PERMISSION_GRANTED : PackageManager.PERMISSION_DENIED);
17283d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    }
17293d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme
1730ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN    private void expectNetworkState(boolean roaming) throws Exception {
17310a5570d49df7d438b618616e439192f3c216cfe8Jeff Sharkey        when(mCarrierConfigManager.getConfigForSubId(eq(TEST_SUB_ID)))
17320a5570d49df7d438b618616e439192f3c216cfe8Jeff Sharkey                .thenReturn(CarrierConfigManager.getDefaultConfig());
1733bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey        when(mConnManager.getAllNetworkState()).thenReturn(new NetworkState[] {
1734bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey                new NetworkState(buildNetworkInfo(),
1735bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey                        buildLinkProperties(TEST_IFACE),
1736ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN                        buildNetworkCapabilities(TEST_SUB_ID, roaming),
1737bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey                        new Network(TEST_NET_ID), TEST_IMSI, null)
1738bfb43ea9e684e62644cecf7f037c4087bfaa1e0fJeff Sharkey        });
17398e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey    }
17408e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey
1741ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN    private void expectMobileDefaults() throws Exception {
1742ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN        when(mSubscriptionManager.getActiveSubscriptionIdList()).thenReturn(
1743ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN                new int[] { TEST_SUB_ID });
1744ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN        when(mTelephonyManager.getSubscriberId(TEST_SUB_ID)).thenReturn(TEST_IMSI);
1745ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN        expectNetworkState(false /* roaming */);
1746ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN    }
1747ed6d2ca369a03fd7a357405eb36d6182e187973bRemi NGUYEN VAN
1748ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme    private void verifyAdvisePersistThreshold() throws Exception {
1749ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme        verify(mStatsService).advisePersistThreshold(anyLong());
17500cf6de0c930c9082b7bffdb9824e4a7c7832b6dfJeff Sharkey    }
17510cf6de0c930c9082b7bffdb9824e4a7c7832b6dfJeff Sharkey
17527ee8658453fe4efe04781bea9a14368e1d5ff41fJeff Sharkey    private static class TestAbstractFuture<T> extends AbstractFuture<T> {
17534414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey        @Override
17547ee8658453fe4efe04781bea9a14368e1d5ff41fJeff Sharkey        public T get() throws InterruptedException, ExecutionException {
17554414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey            try {
17564414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey                return get(5, TimeUnit.SECONDS);
17574414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey            } catch (TimeoutException e) {
17584414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey                throw new RuntimeException(e);
17594414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey            }
17604414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey        }
17617ee8658453fe4efe04781bea9a14368e1d5ff41fJeff Sharkey    }
17624414cea13908b8230640f84ef39603d68ff9c377Jeff Sharkey
1763af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey    private static void assertTimeEquals(long expected, long actual) {
1764af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey        if (expected != actual) {
1765af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey            fail("expected " + formatTime(expected) + " but was actually " + formatTime(actual));
1766af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey        }
1767af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey    }
1768af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey
1769af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey    private static String formatTime(long millis) {
177053313d7e8153982f842910118371e1dc061248cdJeff Sharkey        return Instant.ofEpochMilli(millis) + " [" + millis + "]";
1771af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey    }
1772af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey
1773af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey    private static void assertEqualsFuzzy(long expected, long actual, long fuzzy) {
1774af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey        final long low = expected - fuzzy;
1775af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey        final long high = expected + fuzzy;
1776af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey        if (actual < low || actual > high) {
177753313d7e8153982f842910118371e1dc061248cdJeff Sharkey            fail("value " + formatTime(actual) + " is outside [" + formatTime(low) + ","
177853313d7e8153982f842910118371e1dc061248cdJeff Sharkey                    + formatTime(high) + "]");
1779af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey        }
1780af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey    }
1781af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey
1782af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey    private static void assertUnique(LinkedHashSet<Long> seen, Long value) {
1783af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey        if (!seen.add(value)) {
1784af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey            fail("found duplicate time " + value + " in series " + seen.toString());
1785af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey        }
1786af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey    }
1787af82ea2abf53b6825fbbce23434419527d8e8b5cJeff Sharkey
178841ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey    private static void assertNotificationType(int expected, String actualTag) {
1789ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme        assertEquals("notification type mismatch for '" + actualTag +"'",
179041ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey                Integer.toString(expected), actualTag.substring(actualTag.lastIndexOf(':') + 1));
179141ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey    }
179241ff7ec82422a5b6d00892afdb3232bc0e53d851Jeff Sharkey
1793e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme    private void assertUidPolicy(int uid, int expected) {
1794e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme        final int actual = mService.getUidPolicy(uid);
1795e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme        if (expected != actual) {
1796e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme            fail("Wrong policy for UID " + uid + ": expected " + uidPoliciesToString(expected)
1797e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme                    + ", actual " + uidPoliciesToString(actual));
1798e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme        }
1799e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme    }
1800e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme
180146b451fa7da6c0323e80616409cf467d5b1fd01fFelipe Leme    private void assertWhitelistUids(int... uids) {
180257e3d310913ff61ae63c66fcf3d7b64ab9d741a6Felipe Leme        assertContainsInAnyOrder(mService.getUidsWithPolicy(POLICY_ALLOW_METERED_BACKGROUND), uids);
180346b451fa7da6c0323e80616409cf467d5b1fd01fFelipe Leme    }
180446b451fa7da6c0323e80616409cf467d5b1fd01fFelipe Leme
18053d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    private void assertRestrictBackgroundOn() throws Exception {
18063d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        assertTrue("restrictBackground should be set", mService.getRestrictBackground());
18073d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    }
18083d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme
18093d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    private void assertRestrictBackgroundOff() throws Exception {
18103d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        assertFalse("restrictBackground should not be set", mService.getRestrictBackground());
18113d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    }
18123d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme
18133d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    private FutureIntent newRestrictBackgroundChangedFuture() {
18143d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        return mServiceContext
18153d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme                .nextBroadcastIntent(ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED);
18163d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    }
18173d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme
18183d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    private void assertRestrictBackgroundChangedReceived(Future<Intent> future,
18193d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme            String expectedPackage) throws Exception {
18203d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        final String action = ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED;
18213d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        final Intent intent = future.get(5, TimeUnit.SECONDS);
18223d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        assertNotNull("Didn't get a " + action + "intent in 5 seconds");
18233d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        assertEquals("Wrong package on " + action + " intent", expectedPackage, intent.getPackage());
18243d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    }
18253d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme
1826e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme    // TODO: replace by Truth, Hamcrest, or a similar tool.
1827e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme    private void assertContainsInAnyOrder(int[] actual, int...expected) {
1828e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme        final StringBuilder errors = new StringBuilder();
1829e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme        if (actual.length != expected.length) {
1830e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme            errors.append("\tsize does not match\n");
1831e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme        }
1832e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme        final List<Integer> actualList =
1833e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme                Arrays.stream(actual).boxed().collect(Collectors.<Integer>toList());
1834e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme        final List<Integer> expectedList =
1835e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme                Arrays.stream(expected).boxed().collect(Collectors.<Integer>toList());
1836e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme        if (!actualList.containsAll(expectedList)) {
1837e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme            errors.append("\tmissing elements on actual list\n");
1838e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme        }
1839e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme        if (!expectedList.containsAll(actualList)) {
1840e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme            errors.append("\tmissing elements on expected list\n");
1841e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme        }
1842e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme        if (errors.length() > 0) {
1843e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme            fail("assertContainsInAnyOrder(expected=" + Arrays.toString(expected)
1844e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme                    + ", actual=" + Arrays.toString(actual) +") failed: \n" + errors);
1845e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme        }
1846e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme    }
1847e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme
18488e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey    private long getElapsedRealtime() {
18498e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey        return mElapsedRealtime;
18508e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey    }
18518e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey
18528e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey    private void setCurrentTimeMillis(long currentTimeMillis) {
185317bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey        RecurrenceRule.sClock = Clock.fixed(Instant.ofEpochMilli(currentTimeMillis),
185417bebd2fd7d3af0bc648172da6ae36f8b55ad7afJeff Sharkey                ZoneId.systemDefault());
18558e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey        mStartTime = currentTimeMillis;
18568e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey        mElapsedRealtime = 0L;
18578e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey    }
18588e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey
18598e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey    private long currentTimeMillis() {
18608e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey        return mStartTime + mElapsedRealtime;
18618e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey    }
18628e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey
18638e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey    private void incrementCurrentTime(long duration) {
18648e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey        mElapsedRealtime += duration;
18658e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey    }
18668e28b7d78232f6cf08739ca0d129cc7f9e650801Jeff Sharkey
18673d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    private FutureIntent mRestrictBackgroundChanged;
18683d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme
18693d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    private void setRestrictBackground(boolean flag) throws Exception {
18703d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        mService.setRestrictBackground(flag);
18713d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        // Sanity check.
18723d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        assertEquals("restrictBackground not set", flag, mService.getRestrictBackground());
18733d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme    }
18743d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme
1875ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme    /**
1876ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme     * Creates a mock and registers it to {@link LocalServices}.
1877ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme     */
18789f27e7ad34054e7e1d742845983a355eea63f205Felipe Leme    private static <T> T addLocalServiceMock(Class<T> clazz) {
1879ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme        final T mock = mock(clazz);
1880ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme        LocalServices.addService(clazz, mock);
1881ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme        return mock;
1882ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme    }
1883ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme
1884ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme    /**
1885ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme     * Custom Mockito answer used to verify async {@link INetworkPolicyListener} calls.
1886ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme     *
1887ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme     * <p>Typical usage:
1888ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme     * <pre><code>
1889ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme     *    mPolicyListener.expect().someCallback(any());
1890ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme     *    // do something on objects under test
1891ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme     *    mPolicyListener.waitAndVerify().someCallback(eq(expectedValue));
1892ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme     * </code></pre>
1893ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme     */
1894ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme    final class NetworkPolicyListenerAnswer implements Answer<Void> {
1895ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme        private CountDownLatch latch;
1896ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme        private final INetworkPolicyListener listener;
1897ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme
1898ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme        NetworkPolicyListenerAnswer(NetworkPolicyManagerService service) {
1899ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme            this.listener = mock(INetworkPolicyListener.class);
1900ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme            // RemoteCallbackList needs a binder to use as key
1901ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme            when(listener.asBinder()).thenReturn(new Binder());
1902ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme            service.registerListener(listener);
1903ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme        }
1904ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme
1905ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme        @Override
1906ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme        public Void answer(InvocationOnMock invocation) throws Throwable {
1907ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme            Log.d(TAG,"counting down on answer: " + invocation);
1908ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme            latch.countDown();
1909ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme            return null;
1910ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme        }
1911ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme
1912ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme        INetworkPolicyListener expect() {
1913ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme            assertNull("expect() called before waitAndVerify()", latch);
1914ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme            latch = new CountDownLatch(1);
1915ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme            return doAnswer(this).when(listener);
1916ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme        }
1917ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme
1918ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme        INetworkPolicyListener waitAndVerify() {
1919ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme            assertNotNull("waitAndVerify() called before expect()", latch);
1920ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme            try {
1921ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme                assertTrue("callback not called in 5 seconds", latch.await(5, TimeUnit.SECONDS));
1922ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme            } catch (InterruptedException e) {
1923ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme                fail("Thread interrupted before callback called");
1924ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme            } finally {
1925ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme                latch = null;
1926ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme            }
1927ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme            return verify(listener, atLeastOnce());
1928ef13466e4505e5320d376ab5b831c13d0ffa31b4Felipe Leme        }
19293d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme
19303d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        INetworkPolicyListener verifyNotCalled() {
19313d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme            return verify(listener, never());
19323d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme        }
19333d3308d3e476f62664a9c3c31e6bc95bc879e49eFelipe Leme
19349599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey    }
1935e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme
1936e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme    private void setNetpolicyXml(Context context) throws Exception {
1937e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme        mPolicyDir = context.getFilesDir();
1938e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme        if (mPolicyDir.exists()) {
1939e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme            IoUtils.deleteContents(mPolicyDir);
1940e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme        }
1941e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme        if (!TextUtils.isEmpty(mNetpolicyXml)) {
1942e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme            final String assetPath = NETPOLICY_DIR + "/" + mNetpolicyXml;
1943e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme            final File netConfigFile = new File(mPolicyDir, "netpolicy.xml");
1944e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme            Log.d(TAG, "Creating " + netConfigFile + " from asset " + assetPath);
1945e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme            try (final InputStream in = context.getResources().getAssets().open(assetPath);
1946e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme                    final OutputStream out = new FileOutputStream(netConfigFile)) {
1947e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme                Streams.copy(in, out);
1948e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme            }
1949e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme        }
1950e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme    }
1951e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme
1952e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme    /**
1953e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme     * Annotation used to define the relative path of the {@code netpolicy.xml} file.
1954e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme     */
1955e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme    @Retention(RetentionPolicy.RUNTIME)
1956e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme    @Target(ElementType.METHOD)
1957e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme    public @interface NetPolicyXml {
1958e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme
1959e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme        public String value() default "";
1960e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme
1961e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme    }
1962e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme
1963e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme    /**
1964e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme     * Rule used to set {@code mNetPolicyXml} according to the {@link NetPolicyXml} annotation.
1965e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme     */
1966e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme    public static class NetPolicyMethodRule implements MethodRule {
1967e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme
1968e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme        @Override
1969e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme        public Statement apply(Statement base, FrameworkMethod method, Object target) {
1970e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme            for (Annotation annotation : method.getAnnotations()) {
1971e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme                if ((annotation instanceof NetPolicyXml)) {
1972e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme                    final String path = ((NetPolicyXml) annotation).value();
1973e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme                    if (!path.isEmpty()) {
1974e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme                        ((NetworkPolicyManagerServiceTest) target).mNetpolicyXml = path;
1975e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme                        break;
1976e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme                    }
1977e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme                }
1978e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme            }
1979e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme            return base;
1980e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme        }
1981e88729d3a106807a094ed15891e0d2ef4fb7f73dFelipe Leme    }
19829599cc5f21152860af9d18015b1398b50743da76Jeff Sharkey}
1983