blob: b4dc94192f24576c18a05a12dafba87ed871f17a [file] [log] [blame]
Jeff Sharkey9599cc52011-05-22 14:59:31 -07001/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server;
18
Erik Klinef851d6d2015-04-20 16:03:48 +090019import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
Jeff Sharkey21c9c452011-06-07 12:26:43 -070020import static android.net.ConnectivityManager.TYPE_WIFI;
Remi NGUYEN VANed6d2ca2018-04-04 11:12:51 +090021import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING;
Jeff Sharkey2e471452018-01-19 18:02:47 +090022import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
Jeff Sharkeyaf82ea22011-08-04 15:38:48 -070023import static android.net.NetworkPolicy.LIMIT_DISABLED;
Ammar Aijazi6ce48e22017-03-28 15:43:22 -070024import static android.net.NetworkPolicy.SNOOZE_NEVER;
Jeff Sharkeyaf82ea22011-08-04 15:38:48 -070025import static android.net.NetworkPolicy.WARNING_DISABLED;
Felipe Leme46b451f2016-08-19 08:46:17 -070026import static android.net.NetworkPolicyManager.POLICY_ALLOW_METERED_BACKGROUND;
Jeff Sharkey9599cc52011-05-22 14:59:31 -070027import static android.net.NetworkPolicyManager.POLICY_NONE;
Jeff Sharkeyfdfef572011-06-16 15:07:48 -070028import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND;
Felipe Lemee88729d2016-08-17 16:43:01 -070029import static android.net.NetworkPolicyManager.uidPoliciesToString;
Jeff Sharkeye0c29952018-02-20 17:24:55 -070030import static android.net.NetworkStats.IFACE_ALL;
31import static android.net.NetworkStats.SET_ALL;
32import static android.net.NetworkStats.TAG_ALL;
Ammar Aijazi6ce48e22017-03-28 15:43:22 -070033import static android.net.NetworkTemplate.buildTemplateMobileAll;
Remi NGUYEN VANed6d2ca2018-04-04 11:12:51 +090034import static android.net.NetworkTemplate.buildTemplateWifi;
Jeff Sharkey241dde22012-02-03 14:50:07 -080035import static android.net.TrafficStats.MB_IN_BYTES;
Ammar Aijazi6ce48e22017-03-28 15:43:22 -070036import static android.telephony.CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED;
Ammar Aijazi6ce48e22017-03-28 15:43:22 -070037import static android.telephony.CarrierConfigManager.DATA_CYCLE_THRESHOLD_DISABLED;
Jeff Sharkey53313d72017-07-13 16:47:32 -060038import static android.telephony.CarrierConfigManager.DATA_CYCLE_USE_PLATFORM_DEFAULT;
Ammar Aijazi6ce48e22017-03-28 15:43:22 -070039import static android.telephony.CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG;
40import static android.telephony.CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG;
41import static android.telephony.CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT;
Jeff Sharkey36b414b2018-03-30 11:00:03 -060042import static android.telephony.SubscriptionPlan.BYTES_UNLIMITED;
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -070043import static android.telephony.SubscriptionPlan.LIMIT_BEHAVIOR_DISABLED;
Jeff Sharkey9bf31502012-03-09 17:07:21 -080044import static android.text.format.Time.TIMEZONE_UTC;
Felipe Lemeef134662016-08-10 14:46:39 -070045
Jeff Sharkey36b414b2018-03-30 11:00:03 -060046import static com.android.server.net.NetworkPolicyManagerInternal.QUOTA_TYPE_JOBS;
47import static com.android.server.net.NetworkPolicyManagerInternal.QUOTA_TYPE_MULTIPATH;
Remi NGUYEN VANed6d2ca2018-04-04 11:12:51 +090048import static com.android.server.net.NetworkPolicyManagerService.OPPORTUNISTIC_QUOTA_UNKNOWN;
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -070049import static com.android.server.net.NetworkPolicyManagerService.TYPE_LIMIT;
50import static com.android.server.net.NetworkPolicyManagerService.TYPE_LIMIT_SNOOZED;
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -070051import static com.android.server.net.NetworkPolicyManagerService.TYPE_RAPID;
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -070052import static com.android.server.net.NetworkPolicyManagerService.TYPE_WARNING;
Jeff Sharkey53313d72017-07-13 16:47:32 -060053
Felipe Leme9f27e7a2016-08-12 15:19:40 -070054import static org.junit.Assert.assertEquals;
55import static org.junit.Assert.assertFalse;
56import static org.junit.Assert.assertNotNull;
57import static org.junit.Assert.assertNull;
58import static org.junit.Assert.assertTrue;
59import static org.junit.Assert.fail;
Jeff Sharkey53313d72017-07-13 16:47:32 -060060import static org.mockito.ArgumentMatchers.any;
Sudheer Shanka543339f2017-07-28 15:18:07 -070061import static org.mockito.ArgumentMatchers.anyBoolean;
Jeff Sharkey53313d72017-07-13 16:47:32 -060062import static org.mockito.ArgumentMatchers.anyInt;
63import static org.mockito.ArgumentMatchers.anyLong;
64import static org.mockito.ArgumentMatchers.anyString;
65import static org.mockito.ArgumentMatchers.eq;
66import static org.mockito.ArgumentMatchers.isA;
67import static org.mockito.ArgumentMatchers.isNull;
jackqdyulei29c82ab2017-03-10 14:09:16 -080068import static org.mockito.Mockito.atLeast;
Felipe Lemeef134662016-08-10 14:46:39 -070069import static org.mockito.Mockito.atLeastOnce;
70import static org.mockito.Mockito.doAnswer;
Remi NGUYEN VANed6d2ca2018-04-04 11:12:51 +090071import static org.mockito.Mockito.doNothing;
Felipe Lemeef134662016-08-10 14:46:39 -070072import static org.mockito.Mockito.mock;
Felipe Leme3d3308d2016-08-23 17:41:47 -070073import static org.mockito.Mockito.never;
Jeff Sharkey2e471452018-01-19 18:02:47 +090074import static org.mockito.Mockito.reset;
Felipe Lemeef134662016-08-10 14:46:39 -070075import static org.mockito.Mockito.verify;
76import static org.mockito.Mockito.when;
77
Felipe Leme3d3308d2016-08-23 17:41:47 -070078import android.Manifest;
Felipe Lemeef134662016-08-10 14:46:39 -070079import android.app.ActivityManager;
Sudheer Shankae7361852017-03-07 11:51:46 -080080import android.app.ActivityManagerInternal;
Jeff Sharkey9599cc52011-05-22 14:59:31 -070081import android.app.IActivityManager;
Felipe Lemeef134662016-08-10 14:46:39 -070082import android.app.IUidObserver;
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -070083import android.app.Notification;
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -070084import android.app.NotificationManager;
Felipe Lemeef134662016-08-10 14:46:39 -070085import android.app.usage.UsageStatsManagerInternal;
86import android.content.Context;
Jeff Sharkey9599cc52011-05-22 14:59:31 -070087import android.content.Intent;
Felipe Lemeef134662016-08-10 14:46:39 -070088import android.content.pm.ApplicationInfo;
Felipe Leme3d3308d2016-08-23 17:41:47 -070089import android.content.pm.IPackageManager;
Jeff Sharkey4414cea2011-06-24 17:05:24 -070090import android.content.pm.PackageInfo;
Jeff Sharkey9599cc52011-05-22 14:59:31 -070091import android.content.pm.PackageManager;
Jeff Sharkey4414cea2011-06-24 17:05:24 -070092import android.content.pm.Signature;
Felipe Leme3d3308d2016-08-23 17:41:47 -070093import android.net.ConnectivityManager;
Jeff Sharkey21c9c452011-06-07 12:26:43 -070094import android.net.IConnectivityManager;
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -070095import android.net.INetworkManagementEventObserver;
Jeff Sharkey9599cc52011-05-22 14:59:31 -070096import android.net.INetworkPolicyListener;
Jeff Sharkey21c9c452011-06-07 12:26:43 -070097import android.net.LinkProperties;
Jeff Sharkey2e471452018-01-19 18:02:47 +090098import android.net.Network;
Stephen Chena1c92b72017-02-06 13:18:11 -080099import android.net.NetworkCapabilities;
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700100import android.net.NetworkInfo;
101import android.net.NetworkInfo.DetailedState;
102import android.net.NetworkPolicy;
103import android.net.NetworkState;
104import android.net.NetworkStats;
Jeff Sharkey2e471452018-01-19 18:02:47 +0900105import android.net.NetworkStatsHistory;
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -0700106import android.net.NetworkTemplate;
Jeff Sharkey2e471452018-01-19 18:02:47 +0900107import android.net.StringNetworkSpecifier;
Jeff Sharkey9599cc52011-05-22 14:59:31 -0700108import android.os.Binder;
Ashish Sharma50fd36d2011-06-15 19:34:53 -0700109import android.os.INetworkManagementService;
Ammar Aijazi6ce48e22017-03-28 15:43:22 -0700110import android.os.PersistableBundle;
Felipe Lemeef134662016-08-10 14:46:39 -0700111import android.os.PowerManagerInternal;
jackqdyulei29c82ab2017-03-10 14:09:16 -0800112import android.os.PowerSaveState;
Ammar Aijazi6ce48e22017-03-28 15:43:22 -0700113import android.os.RemoteException;
Jeff Sharkey9911a282018-02-14 22:29:11 -0700114import android.os.SimpleClock;
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700115import android.os.SystemClock;
Dianne Hackbornf02b60a2012-08-16 10:48:27 -0700116import android.os.UserHandle;
Felipe Leme9f27e7a2016-08-12 15:19:40 -0700117import android.support.test.InstrumentationRegistry;
118import android.support.test.runner.AndroidJUnit4;
Ammar Aijazi6ce48e22017-03-28 15:43:22 -0700119import android.telephony.CarrierConfigManager;
120import android.telephony.SubscriptionManager;
Jeff Sharkey2e471452018-01-19 18:02:47 +0900121import android.telephony.SubscriptionPlan;
Ammar Aijazi6ce48e22017-03-28 15:43:22 -0700122import android.telephony.TelephonyManager;
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -0700123import android.test.suitebuilder.annotation.MediumTest;
Felipe Lemee88729d2016-08-17 16:43:01 -0700124import android.text.TextUtils;
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700125import android.text.format.Time;
Jeff Sharkey2e471452018-01-19 18:02:47 +0900126import android.util.DataUnit;
Felipe Lemeef134662016-08-10 14:46:39 -0700127import android.util.Log;
Jeff Sharkey0fc6d032018-03-30 16:25:11 -0600128import android.util.Range;
Jeff Sharkey17bebd22017-07-19 21:00:38 -0600129import android.util.RecurrenceRule;
Jeff Sharkey9599cc52011-05-22 14:59:31 -0700130
Ammar Aijazi6ce48e22017-03-28 15:43:22 -0700131import com.android.internal.telephony.PhoneConstants;
Lorenzo Colitti281a17c2016-10-28 12:56:03 +0900132import com.android.internal.util.test.BroadcastInterceptingContext;
133import com.android.internal.util.test.BroadcastInterceptingContext.FutureIntent;
Felipe Lemeef134662016-08-10 14:46:39 -0700134import com.android.server.net.NetworkPolicyManagerInternal;
Jeff Sharkey9599cc52011-05-22 14:59:31 -0700135import com.android.server.net.NetworkPolicyManagerService;
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700136import com.android.server.net.NetworkStatsManagerInternal;
Felipe Lemeef134662016-08-10 14:46:39 -0700137
138import libcore.io.IoUtils;
Felipe Lemee88729d2016-08-17 16:43:01 -0700139import libcore.io.Streams;
Felipe Lemeef134662016-08-10 14:46:39 -0700140
Jeff Sharkey4414cea2011-06-24 17:05:24 -0700141import com.google.common.util.concurrent.AbstractFuture;
Jeff Sharkey9599cc52011-05-22 14:59:31 -0700142
Felipe Leme9f27e7a2016-08-12 15:19:40 -0700143import org.junit.After;
144import org.junit.Before;
Felipe Lemee88729d2016-08-17 16:43:01 -0700145import org.junit.Rule;
Felipe Leme9f27e7a2016-08-12 15:19:40 -0700146import org.junit.Test;
Felipe Lemee88729d2016-08-17 16:43:01 -0700147import org.junit.rules.MethodRule;
Felipe Leme9f27e7a2016-08-12 15:19:40 -0700148import org.junit.runner.RunWith;
Felipe Lemee88729d2016-08-17 16:43:01 -0700149import org.junit.runners.model.FrameworkMethod;
150import org.junit.runners.model.Statement;
Felipe Lemeef134662016-08-10 14:46:39 -0700151import org.mockito.ArgumentCaptor;
152import org.mockito.Mock;
153import org.mockito.MockitoAnnotations;
154import org.mockito.invocation.InvocationOnMock;
155import org.mockito.stubbing.Answer;
Jeff Sharkey9599cc52011-05-22 14:59:31 -0700156
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700157import java.io.File;
Felipe Lemee88729d2016-08-17 16:43:01 -0700158import java.io.FileOutputStream;
159import java.io.InputStream;
160import java.io.OutputStream;
161import java.lang.annotation.Annotation;
162import java.lang.annotation.ElementType;
163import java.lang.annotation.Retention;
164import java.lang.annotation.RetentionPolicy;
165import java.lang.annotation.Target;
Jeff Sharkey17bebd22017-07-19 21:00:38 -0600166import java.time.Clock;
Jeff Sharkey53313d72017-07-13 16:47:32 -0600167import java.time.Instant;
Jeff Sharkey17bebd22017-07-19 21:00:38 -0600168import java.time.Period;
169import java.time.ZoneId;
Jeff Sharkey9911a282018-02-14 22:29:11 -0700170import java.time.ZoneOffset;
Jeff Sharkey53313d72017-07-13 16:47:32 -0600171import java.time.ZonedDateTime;
Felipe Lemee88729d2016-08-17 16:43:01 -0700172import java.util.Arrays;
Ammar Aijazi6ce48e22017-03-28 15:43:22 -0700173import java.util.Calendar;
Jeff Sharkey53313d72017-07-13 16:47:32 -0600174import java.util.Iterator;
Jeff Sharkeyaf82ea22011-08-04 15:38:48 -0700175import java.util.LinkedHashSet;
Felipe Lemeef134662016-08-10 14:46:39 -0700176import java.util.List;
177import java.util.concurrent.CountDownLatch;
Jeff Sharkey4414cea2011-06-24 17:05:24 -0700178import java.util.concurrent.ExecutionException;
Jeff Sharkey9599cc52011-05-22 14:59:31 -0700179import java.util.concurrent.Future;
Jeff Sharkey4414cea2011-06-24 17:05:24 -0700180import java.util.concurrent.TimeUnit;
181import java.util.concurrent.TimeoutException;
Felipe Lemee88729d2016-08-17 16:43:01 -0700182import java.util.stream.Collectors;
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -0700183
Jeff Sharkey9599cc52011-05-22 14:59:31 -0700184/**
185 * Tests for {@link NetworkPolicyManagerService}.
Felipe Lemeb8d572e2016-12-05 13:41:43 -0800186 *
187 * <p>Typical usage:
188 *
189 * <pre><code>
190 m -j32 FrameworksServicesTests && adb install -r -g \
191 ${ANDROID_PRODUCT_OUT}/data/app/FrameworksServicesTests/FrameworksServicesTests.apk && \
192 adb shell am instrument -e class "com.android.server.NetworkPolicyManagerServiceTest" -w \
193 "com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner"
194 * </code></pre>
Jeff Sharkey9599cc52011-05-22 14:59:31 -0700195 */
Felipe Leme9f27e7a2016-08-12 15:19:40 -0700196@RunWith(AndroidJUnit4.class)
Felipe Leme3d3308d2016-08-23 17:41:47 -0700197@MediumTest
Felipe Leme9f27e7a2016-08-12 15:19:40 -0700198public class NetworkPolicyManagerServiceTest {
Jeff Sharkey9599cc52011-05-22 14:59:31 -0700199 private static final String TAG = "NetworkPolicyManagerServiceTest";
200
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700201 private static final long TEST_START = 1194220800000L;
202 private static final String TEST_IFACE = "test0";
Jeff Sharkeye8914c32012-05-01 16:26:09 -0700203 private static final String TEST_SSID = "AndroidAP";
Jeff Sharkey2e471452018-01-19 18:02:47 +0900204 private static final String TEST_IMSI = "310210";
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -0700205 private static final int TEST_SUB_ID = 42;
206 private static final int TEST_NET_ID = 24;
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700207
Remi NGUYEN VANed6d2ca2018-04-04 11:12:51 +0900208 private static NetworkTemplate sTemplateWifi = buildTemplateWifi(TEST_SSID);
209 private static NetworkTemplate sTemplateMobileAll = buildTemplateMobileAll(TEST_IMSI);
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -0700210
Felipe Lemee88729d2016-08-17 16:43:01 -0700211 /**
212 * Path on assets where files used by {@link NetPolicyXml} are located.
213 */
214 private static final String NETPOLICY_DIR = "NetworkPolicyManagerServiceTest/netpolicy";
215
Jeff Sharkey9599cc52011-05-22 14:59:31 -0700216 private BroadcastInterceptingContext mServiceContext;
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700217 private File mPolicyDir;
Jeff Sharkey9599cc52011-05-22 14:59:31 -0700218
Felipe Lemee88729d2016-08-17 16:43:01 -0700219 /**
220 * Relative path of the XML file that will be used as {@code netpolicy.xml}.
221 *
222 * <p>Typically set through a {@link NetPolicyXml} annotation in the test method.
223 */
224 private String mNetpolicyXml;
225
Felipe Lemeef134662016-08-10 14:46:39 -0700226 private @Mock IActivityManager mActivityManager;
Felipe Lemeef134662016-08-10 14:46:39 -0700227 private @Mock INetworkManagementService mNetworkManager;
Felipe Lemeef134662016-08-10 14:46:39 -0700228 private @Mock IConnectivityManager mConnManager;
Remi NGUYEN VANed6d2ca2018-04-04 11:12:51 +0900229 private @Mock ConnectivityManager mConnectivityManager;
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -0700230 private @Mock NotificationManager mNotifManager;
Felipe Lemeef134662016-08-10 14:46:39 -0700231 private @Mock PackageManager mPackageManager;
Felipe Leme3d3308d2016-08-23 17:41:47 -0700232 private @Mock IPackageManager mIpm;
Ammar Aijazi6ce48e22017-03-28 15:43:22 -0700233 private @Mock SubscriptionManager mSubscriptionManager;
234 private @Mock CarrierConfigManager mCarrierConfigManager;
235 private @Mock TelephonyManager mTelephonyManager;
Jeff Sharkey9599cc52011-05-22 14:59:31 -0700236
Remi NGUYEN VANed6d2ca2018-04-04 11:12:51 +0900237 private ArgumentCaptor<ConnectivityManager.NetworkCallback> mNetworkCallbackCaptor =
238 ArgumentCaptor.forClass(ConnectivityManager.NetworkCallback.class);
239
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700240 private ActivityManagerInternal mActivityManagerInternal;
241 private NetworkStatsManagerInternal mStatsService;
Sudheer Shankae7361852017-03-07 11:51:46 -0800242
Felipe Lemeef134662016-08-10 14:46:39 -0700243 private IUidObserver mUidObserver;
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -0700244 private INetworkManagementEventObserver mNetworkObserver;
Jeff Sharkey9599cc52011-05-22 14:59:31 -0700245
Felipe Lemeef134662016-08-10 14:46:39 -0700246 private NetworkPolicyListenerAnswer mPolicyListener;
247 private NetworkPolicyManagerService mService;
Jeff Sharkey9599cc52011-05-22 14:59:31 -0700248
Sudheer Shankaed25ce62017-03-29 20:46:30 -0700249 /**
250 * In some of the tests while initializing NetworkPolicyManagerService,
251 * ACTION_RESTRICT_BACKGROUND_CHANGED is broadcasted. This is for capturing that broadcast.
252 */
253 private FutureIntent mFutureIntent;
254
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -0700255 private long mStartTime;
256 private long mElapsedRealtime;
257
Jeff Sharkeycae04a22012-03-22 15:18:52 -0700258 private static final int USER_ID = 0;
Ammar Aijazi6ce48e22017-03-28 15:43:22 -0700259 private static final int FAKE_SUB_ID = 3737373;
260 private static final String FAKE_SUBSCRIBER_ID = "FAKE_SUB_ID";
261 private static final int DEFAULT_CYCLE_DAY = 1;
262 private static final int INVALID_CARRIER_CONFIG_VALUE = -9999;
263 private long mDefaultWarningBytes; // filled in with the actual default before tests are run
264 private long mDefaultLimitBytes; // filled in with the actual default before tests are run
Jeff Sharkeycae04a22012-03-22 15:18:52 -0700265
Felipe Lemee88729d2016-08-17 16:43:01 -0700266 private static final int APP_ID_A = android.os.Process.FIRST_APPLICATION_UID + 4;
267 private static final int APP_ID_B = android.os.Process.FIRST_APPLICATION_UID + 8;
268 private static final int APP_ID_C = android.os.Process.FIRST_APPLICATION_UID + 15;
269 private static final int APP_ID_D = android.os.Process.FIRST_APPLICATION_UID + 16;
270 private static final int APP_ID_E = android.os.Process.FIRST_APPLICATION_UID + 23;
271 private static final int APP_ID_F = android.os.Process.FIRST_APPLICATION_UID + 42;
Jeff Sharkeycae04a22012-03-22 15:18:52 -0700272
Dianne Hackbornf02b60a2012-08-16 10:48:27 -0700273 private static final int UID_A = UserHandle.getUid(USER_ID, APP_ID_A);
274 private static final int UID_B = UserHandle.getUid(USER_ID, APP_ID_B);
Felipe Lemee88729d2016-08-17 16:43:01 -0700275 private static final int UID_C = UserHandle.getUid(USER_ID, APP_ID_C);
276 private static final int UID_D = UserHandle.getUid(USER_ID, APP_ID_D);
277 private static final int UID_E = UserHandle.getUid(USER_ID, APP_ID_E);
278 private static final int UID_F = UserHandle.getUid(USER_ID, APP_ID_F);
Jeff Sharkey9599cc52011-05-22 14:59:31 -0700279
Felipe Lemeef134662016-08-10 14:46:39 -0700280 private static final String PKG_NAME_A = "name.is.A,pkg.A";
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700281 private static final String PKG_NAME_B = "name.is.B,pkg.B";
282 private static final String PKG_NAME_C = "name.is.C,pkg.C";
Jeff Sharkey9599cc52011-05-22 14:59:31 -0700283
Felipe Lemee88729d2016-08-17 16:43:01 -0700284 public final @Rule NetPolicyMethodRule mNetPolicyXmlRule = new NetPolicyMethodRule();
285
Jeff Sharkey9911a282018-02-14 22:29:11 -0700286 private final Clock mClock = new SimpleClock(ZoneOffset.UTC) {
287 @Override
288 public long millis() {
289 return currentTimeMillis();
290 }
291 };
292
Sudheer Shankaed25ce62017-03-29 20:46:30 -0700293 private void registerLocalServices() {
Felipe Leme9f27e7a2016-08-12 15:19:40 -0700294 addLocalServiceMock(DeviceIdleController.LocalService.class);
Sudheer Shankaed25ce62017-03-29 20:46:30 -0700295
Felipe Leme9f27e7a2016-08-12 15:19:40 -0700296 final UsageStatsManagerInternal usageStats =
297 addLocalServiceMock(UsageStatsManagerInternal.class);
298 when(usageStats.getIdleUidsForUser(anyInt())).thenReturn(new int[]{});
Sudheer Shankaed25ce62017-03-29 20:46:30 -0700299
Sudheer Shankae7361852017-03-07 11:51:46 -0800300 mActivityManagerInternal = addLocalServiceMock(ActivityManagerInternal.class);
jackqdyulei29c82ab2017-03-10 14:09:16 -0800301
302 final PowerSaveState state = new PowerSaveState.Builder()
303 .setBatterySaverEnabled(false).build();
304 final PowerManagerInternal pmInternal = addLocalServiceMock(PowerManagerInternal.class);
305 when(pmInternal.getLowPowerState(anyInt())).thenReturn(state);
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700306
307 mStatsService = addLocalServiceMock(NetworkStatsManagerInternal.class);
Felipe Leme9f27e7a2016-08-12 15:19:40 -0700308 }
Jeff Sharkey9599cc52011-05-22 14:59:31 -0700309
Felipe Leme9f27e7a2016-08-12 15:19:40 -0700310 @Before
311 public void callSystemReady() throws Exception {
Felipe Lemeef134662016-08-10 14:46:39 -0700312 MockitoAnnotations.initMocks(this);
313
Felipe Leme9f27e7a2016-08-12 15:19:40 -0700314 final Context context = InstrumentationRegistry.getContext();
Felipe Lemeef134662016-08-10 14:46:39 -0700315
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -0700316 setCurrentTimeMillis(TEST_START);
317
Sudheer Shankaed25ce62017-03-29 20:46:30 -0700318 registerLocalServices();
Ammar Aijazi6ce48e22017-03-28 15:43:22 -0700319 // Intercept various broadcasts, and pretend that uids have packages.
320 // Also return mock service instances for a few critical services.
Felipe Lemeef134662016-08-10 14:46:39 -0700321 mServiceContext = new BroadcastInterceptingContext(context) {
Jeff Sharkey9599cc52011-05-22 14:59:31 -0700322 @Override
323 public PackageManager getPackageManager() {
Felipe Lemeef134662016-08-10 14:46:39 -0700324 return mPackageManager;
Jeff Sharkey9599cc52011-05-22 14:59:31 -0700325 }
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -0700326
327 @Override
328 public void startActivity(Intent intent) {
329 // ignored
330 }
Ammar Aijazi6ce48e22017-03-28 15:43:22 -0700331
332 @Override
333 public Object getSystemService(String name) {
334 switch (name) {
335 case Context.TELEPHONY_SUBSCRIPTION_SERVICE:
336 return mSubscriptionManager;
337 case Context.CARRIER_CONFIG_SERVICE:
338 return mCarrierConfigManager;
339 case Context.TELEPHONY_SERVICE:
340 return mTelephonyManager;
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -0700341 case Context.NOTIFICATION_SERVICE:
342 return mNotifManager;
Remi NGUYEN VANed6d2ca2018-04-04 11:12:51 +0900343 case Context.CONNECTIVITY_SERVICE:
344 return mConnectivityManager;
Ammar Aijazi6ce48e22017-03-28 15:43:22 -0700345 default:
346 return super.getSystemService(name);
347 }
348 }
Jeff Sharkey2e471452018-01-19 18:02:47 +0900349
350 @Override
351 public void enforceCallingOrSelfPermission(String permission, String message) {
352 // Assume that we're AID_SYSTEM
353 }
Jeff Sharkey9599cc52011-05-22 14:59:31 -0700354 };
355
Felipe Lemee88729d2016-08-17 16:43:01 -0700356 setNetpolicyXml(context);
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700357
Felipe Lemeef134662016-08-10 14:46:39 -0700358 doAnswer(new Answer<Void>() {
Jeff Sharkey9599cc52011-05-22 14:59:31 -0700359
Felipe Lemeef134662016-08-10 14:46:39 -0700360 @Override
361 public Void answer(InvocationOnMock invocation) throws Throwable {
362 mUidObserver = (IUidObserver) invocation.getArguments()[0];
363 Log.d(TAG, "set mUidObserver to " + mUidObserver);
364 return null;
365 }
Dianne Hackborn5614bf52016-11-07 17:26:41 -0800366 }).when(mActivityManager).registerUidObserver(any(), anyInt(),
Felipe Lemeb8d572e2016-12-05 13:41:43 -0800367 eq(ActivityManager.PROCESS_STATE_UNKNOWN), isNull(String.class));
Felipe Lemeef134662016-08-10 14:46:39 -0700368
Sudheer Shankaed25ce62017-03-29 20:46:30 -0700369 mFutureIntent = newRestrictBackgroundChangedFuture();
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700370 mService = new NetworkPolicyManagerService(mServiceContext, mActivityManager,
Jeff Sharkey9911a282018-02-14 22:29:11 -0700371 mNetworkManager, mIpm, mClock, mPolicyDir, true);
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700372 mService.bindConnectivityManager(mConnManager);
Felipe Lemeef134662016-08-10 14:46:39 -0700373 mPolicyListener = new NetworkPolicyListenerAnswer(mService);
Jeff Sharkey9599cc52011-05-22 14:59:31 -0700374
Felipe Lemeef134662016-08-10 14:46:39 -0700375 // Sets some common expectations.
376 when(mPackageManager.getPackageInfo(anyString(), anyInt())).thenAnswer(
377 new Answer<PackageInfo>() {
Jeff Sharkey9599cc52011-05-22 14:59:31 -0700378
Felipe Lemeef134662016-08-10 14:46:39 -0700379 @Override
380 public PackageInfo answer(InvocationOnMock invocation) throws Throwable {
381 final String packageName = (String) invocation.getArguments()[0];
382 final PackageInfo info = new PackageInfo();
383 final Signature signature;
384 if ("android".equals(packageName)) {
385 signature = new Signature("F00D");
386 } else {
387 signature = new Signature("DEAD");
388 }
389 info.signatures = new Signature[] {
390 signature
391 };
392 return info;
393 }
394 });
395 when(mPackageManager.getApplicationInfoAsUser(anyString(), anyInt(), anyInt()))
396 .thenReturn(new ApplicationInfo());
397 when(mPackageManager.getPackagesForUid(UID_A)).thenReturn(new String[] {PKG_NAME_A});
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700398 when(mPackageManager.getPackagesForUid(UID_B)).thenReturn(new String[] {PKG_NAME_B});
399 when(mPackageManager.getPackagesForUid(UID_C)).thenReturn(new String[] {PKG_NAME_C});
400 when(mPackageManager.getApplicationInfo(eq(PKG_NAME_A), anyInt()))
401 .thenReturn(buildApplicationInfo(PKG_NAME_A));
402 when(mPackageManager.getApplicationInfo(eq(PKG_NAME_B), anyInt()))
403 .thenReturn(buildApplicationInfo(PKG_NAME_B));
404 when(mPackageManager.getApplicationInfo(eq(PKG_NAME_C), anyInt()))
405 .thenReturn(buildApplicationInfo(PKG_NAME_C));
Felipe Lemeef134662016-08-10 14:46:39 -0700406 when(mNetworkManager.isBandwidthControlEnabled()).thenReturn(true);
Sudheer Shanka543339f2017-07-28 15:18:07 -0700407 when(mNetworkManager.setDataSaverModeEnabled(anyBoolean())).thenReturn(true);
Remi NGUYEN VANed6d2ca2018-04-04 11:12:51 +0900408 doNothing().when(mConnectivityManager)
409 .registerNetworkCallback(any(), mNetworkCallbackCaptor.capture());
Jeff Sharkey9599cc52011-05-22 14:59:31 -0700410
Felipe Lemeef134662016-08-10 14:46:39 -0700411 // Prepare NPMS.
Fyodor Kupolov311b9fa2016-12-02 16:24:35 -0800412 mService.systemReady(mService.networkScoreAndNetworkManagementServiceReady());
Jeff Sharkey9599cc52011-05-22 14:59:31 -0700413
Felipe Lemeef134662016-08-10 14:46:39 -0700414 // catch INetworkManagementEventObserver during systemReady()
Felipe Leme3d3308d2016-08-23 17:41:47 -0700415 final ArgumentCaptor<INetworkManagementEventObserver> networkObserver =
Felipe Lemeef134662016-08-10 14:46:39 -0700416 ArgumentCaptor.forClass(INetworkManagementEventObserver.class);
417 verify(mNetworkManager).registerObserver(networkObserver.capture());
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -0700418 mNetworkObserver = networkObserver.getValue();
Ammar Aijazi6ce48e22017-03-28 15:43:22 -0700419
420 NetworkPolicy defaultPolicy = mService.buildDefaultMobilePolicy(0, "");
421 mDefaultWarningBytes = defaultPolicy.warningBytes;
422 mDefaultLimitBytes = defaultPolicy.limitBytes;
Jeff Sharkey9599cc52011-05-22 14:59:31 -0700423 }
424
Felipe Leme9f27e7a2016-08-12 15:19:40 -0700425 @After
426 public void removeFiles() throws Exception {
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700427 for (File file : mPolicyDir.listFiles()) {
428 file.delete();
429 }
Felipe Leme9f27e7a2016-08-12 15:19:40 -0700430 }
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700431
Felipe Leme9f27e7a2016-08-12 15:19:40 -0700432 @After
433 public void unregisterLocalServices() throws Exception {
434 // Registered by NetworkPolicyManagerService's constructor.
Felipe Lemeef134662016-08-10 14:46:39 -0700435 LocalServices.removeServiceForTest(NetworkPolicyManagerInternal.class);
Sudheer Shankaed25ce62017-03-29 20:46:30 -0700436
437 // Added in registerLocalServices()
438 LocalServices.removeServiceForTest(ActivityManagerInternal.class);
439 LocalServices.removeServiceForTest(PowerManagerInternal.class);
440 LocalServices.removeServiceForTest(DeviceIdleController.LocalService.class);
441 LocalServices.removeServiceForTest(UsageStatsManagerInternal.class);
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700442 LocalServices.removeServiceForTest(NetworkStatsManagerInternal.class);
Jeff Sharkey9599cc52011-05-22 14:59:31 -0700443 }
444
Jeff Sharkey53313d72017-07-13 16:47:32 -0600445 @After
446 public void resetClock() throws Exception {
Jeff Sharkey17bebd22017-07-19 21:00:38 -0600447 RecurrenceRule.sClock = Clock.systemDefaultZone();
Jeff Sharkey53313d72017-07-13 16:47:32 -0600448 }
449
Felipe Lemee88729d2016-08-17 16:43:01 -0700450 @Test
Felipe Leme3d3308d2016-08-23 17:41:47 -0700451 public void testTurnRestrictBackgroundOn() throws Exception {
452 assertRestrictBackgroundOff(); // Sanity check.
453 final FutureIntent futureIntent = newRestrictBackgroundChangedFuture();
454 setRestrictBackground(true);
455 assertRestrictBackgroundChangedReceived(futureIntent, null);
456 }
457
458 @Test
459 @NetPolicyXml("restrict-background-on.xml")
460 public void testTurnRestrictBackgroundOff() throws Exception {
461 assertRestrictBackgroundOn(); // Sanity check.
Sudheer Shankaed25ce62017-03-29 20:46:30 -0700462 assertRestrictBackgroundChangedReceived(mFutureIntent, null);
Felipe Leme3d3308d2016-08-23 17:41:47 -0700463 final FutureIntent futureIntent = newRestrictBackgroundChangedFuture();
464 setRestrictBackground(false);
465 assertRestrictBackgroundChangedReceived(futureIntent, null);
466 }
467
468 /**
469 * Adds whitelist when restrict background is on - app should receive an intent.
470 */
471 @Test
472 @NetPolicyXml("restrict-background-on.xml")
473 public void testAddRestrictBackgroundWhitelist_restrictBackgroundOn() throws Exception {
474 assertRestrictBackgroundOn(); // Sanity check.
Sudheer Shankaed25ce62017-03-29 20:46:30 -0700475 assertRestrictBackgroundChangedReceived(mFutureIntent, null);
Felipe Leme3d3308d2016-08-23 17:41:47 -0700476 addRestrictBackgroundWhitelist(true);
477 }
478
479 /**
480 * Adds whitelist when restrict background is off - app should not receive an intent.
481 */
482 @Test
483 public void testAddRestrictBackgroundWhitelist_restrictBackgroundOff() throws Exception {
484 assertRestrictBackgroundOff(); // Sanity check.
485 addRestrictBackgroundWhitelist(false);
486 }
487
488 private void addRestrictBackgroundWhitelist(boolean expectIntent) throws Exception {
Felipe Leme57e3d312016-08-23 14:42:52 -0700489 // Sanity checks.
490 assertWhitelistUids();
491 assertUidPolicy(UID_A, POLICY_NONE);
492
Felipe Leme3d3308d2016-08-23 17:41:47 -0700493 final FutureIntent futureIntent = newRestrictBackgroundChangedFuture();
Felipe Leme0ecfcd12016-09-06 12:49:48 -0700494 mPolicyListener.expect().onUidPoliciesChanged(anyInt(), anyInt());
Felipe Leme3d3308d2016-08-23 17:41:47 -0700495
Felipe Leme57e3d312016-08-23 14:42:52 -0700496 mService.setUidPolicy(UID_A, POLICY_ALLOW_METERED_BACKGROUND);
Felipe Leme3d3308d2016-08-23 17:41:47 -0700497
498 assertWhitelistUids(UID_A);
Felipe Leme57e3d312016-08-23 14:42:52 -0700499 assertUidPolicy(UID_A, POLICY_ALLOW_METERED_BACKGROUND);
Felipe Leme0ecfcd12016-09-06 12:49:48 -0700500 mPolicyListener.waitAndVerify()
501 .onUidPoliciesChanged(APP_ID_A, POLICY_ALLOW_METERED_BACKGROUND);
Felipe Leme3d3308d2016-08-23 17:41:47 -0700502 if (expectIntent) {
503 assertRestrictBackgroundChangedReceived(futureIntent, PKG_NAME_A);
504 } else {
505 futureIntent.assertNotReceived();
506 }
507 }
508
509 /**
510 * Removes whitelist when restrict background is on - app should receive an intent.
511 */
512 @Test
513 @NetPolicyXml("uidA-whitelisted-restrict-background-on.xml")
514 public void testRemoveRestrictBackgroundWhitelist_restrictBackgroundOn() throws Exception {
515 assertRestrictBackgroundOn(); // Sanity check.
Sudheer Shankaed25ce62017-03-29 20:46:30 -0700516 assertRestrictBackgroundChangedReceived(mFutureIntent, null);
Felipe Leme3d3308d2016-08-23 17:41:47 -0700517 removeRestrictBackgroundWhitelist(true);
518 }
519
520 /**
521 * Removes whitelist when restrict background is off - app should not receive an intent.
522 */
523 @Test
524 @NetPolicyXml("uidA-whitelisted-restrict-background-off.xml")
525 public void testRemoveRestrictBackgroundWhitelist_restrictBackgroundOff() throws Exception {
526 assertRestrictBackgroundOff(); // Sanity check.
527 removeRestrictBackgroundWhitelist(false);
528 }
529
jackqdyulei29c82ab2017-03-10 14:09:16 -0800530 @Test
531 public void testLowPowerModeObserver_ListenersRegistered()
532 throws Exception {
533 PowerManagerInternal pmInternal = LocalServices.getService(PowerManagerInternal.class);
534
535 verify(pmInternal, atLeast(2)).registerLowPowerModeObserver(any());
536 }
537
538 @Test
539 public void updateRestrictBackgroundByLowPowerMode_RestrictOnBeforeBsm_RestrictOnAfterBsm()
540 throws Exception {
541 setRestrictBackground(true);
542 PowerSaveState stateOn = new PowerSaveState.Builder()
543 .setGlobalBatterySaverEnabled(true)
544 .setBatterySaverEnabled(false)
545 .build();
546 mService.updateRestrictBackgroundByLowPowerModeUL(stateOn);
547
548 // RestrictBackground should be on even though battery saver want to turn it off
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700549 assertTrue(mService.getRestrictBackground());
jackqdyulei29c82ab2017-03-10 14:09:16 -0800550
551 PowerSaveState stateOff = new PowerSaveState.Builder()
552 .setGlobalBatterySaverEnabled(false)
553 .setBatterySaverEnabled(false)
554 .build();
555 mService.updateRestrictBackgroundByLowPowerModeUL(stateOff);
556
557 // RestrictBackground should be on, following its previous state
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700558 assertTrue(mService.getRestrictBackground());
jackqdyulei29c82ab2017-03-10 14:09:16 -0800559 }
560
561 @Test
562 public void updateRestrictBackgroundByLowPowerMode_RestrictOffBeforeBsm_RestrictOffAfterBsm()
563 throws Exception {
564 setRestrictBackground(false);
565 PowerSaveState stateOn = new PowerSaveState.Builder()
566 .setGlobalBatterySaverEnabled(true)
567 .setBatterySaverEnabled(true)
568 .build();
569
jackqdyulei29c82ab2017-03-10 14:09:16 -0800570 mService.updateRestrictBackgroundByLowPowerModeUL(stateOn);
571
572 // RestrictBackground should be turned on because of battery saver
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700573 assertTrue(mService.getRestrictBackground());
jackqdyulei29c82ab2017-03-10 14:09:16 -0800574
575 PowerSaveState stateOff = new PowerSaveState.Builder()
576 .setGlobalBatterySaverEnabled(false)
577 .setBatterySaverEnabled(false)
578 .build();
579 mService.updateRestrictBackgroundByLowPowerModeUL(stateOff);
580
581 // RestrictBackground should be off, following its previous state
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700582 assertFalse(mService.getRestrictBackground());
jackqdyulei29c82ab2017-03-10 14:09:16 -0800583 }
584
585 @Test
586 public void updateRestrictBackgroundByLowPowerMode_StatusChangedInBsm_DoNotRestore()
587 throws Exception {
588 setRestrictBackground(true);
589 PowerSaveState stateOn = new PowerSaveState.Builder()
590 .setGlobalBatterySaverEnabled(true)
591 .setBatterySaverEnabled(true)
592 .build();
593 mService.updateRestrictBackgroundByLowPowerModeUL(stateOn);
594
595 // RestrictBackground should still be on
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700596 assertTrue(mService.getRestrictBackground());
jackqdyulei29c82ab2017-03-10 14:09:16 -0800597
598 // User turns off RestrictBackground manually
599 setRestrictBackground(false);
600 PowerSaveState stateOff = new PowerSaveState.Builder().setBatterySaverEnabled(
601 false).build();
602 mService.updateRestrictBackgroundByLowPowerModeUL(stateOff);
603
604 // RestrictBackground should be off because user changes it manually
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700605 assertFalse(mService.getRestrictBackground());
jackqdyulei29c82ab2017-03-10 14:09:16 -0800606 }
607
Felipe Leme3d3308d2016-08-23 17:41:47 -0700608 private void removeRestrictBackgroundWhitelist(boolean expectIntent) throws Exception {
Felipe Leme57e3d312016-08-23 14:42:52 -0700609 // Sanity checks.
610 assertWhitelistUids(UID_A);
611 assertUidPolicy(UID_A, POLICY_ALLOW_METERED_BACKGROUND);
612
Felipe Leme3d3308d2016-08-23 17:41:47 -0700613 final FutureIntent futureIntent = newRestrictBackgroundChangedFuture();
Felipe Leme0ecfcd12016-09-06 12:49:48 -0700614 mPolicyListener.expect().onUidPoliciesChanged(anyInt(), anyInt());
Felipe Leme3d3308d2016-08-23 17:41:47 -0700615
Felipe Leme57e3d312016-08-23 14:42:52 -0700616 mService.setUidPolicy(UID_A, POLICY_NONE);
Felipe Leme3d3308d2016-08-23 17:41:47 -0700617
618 assertWhitelistUids();
Felipe Leme57e3d312016-08-23 14:42:52 -0700619 assertUidPolicy(UID_A, POLICY_NONE);
Felipe Leme0ecfcd12016-09-06 12:49:48 -0700620 mPolicyListener.waitAndVerify().onUidPoliciesChanged(APP_ID_A, POLICY_NONE);
Felipe Leme3d3308d2016-08-23 17:41:47 -0700621 if (expectIntent) {
622 assertRestrictBackgroundChangedReceived(futureIntent, PKG_NAME_A);
623 } else {
624 futureIntent.assertNotReceived();
625 }
626 }
627
628 /**
Felipe Leme57e3d312016-08-23 14:42:52 -0700629 * Adds blacklist when restrict background is on - app should not receive an intent.
Felipe Leme3d3308d2016-08-23 17:41:47 -0700630 */
631 @Test
632 @NetPolicyXml("restrict-background-on.xml")
633 public void testAddRestrictBackgroundBlacklist_restrictBackgroundOn() throws Exception {
634 assertRestrictBackgroundOn(); // Sanity check.
Sudheer Shankaed25ce62017-03-29 20:46:30 -0700635 assertRestrictBackgroundChangedReceived(mFutureIntent, null);
Felipe Leme57e3d312016-08-23 14:42:52 -0700636 addRestrictBackgroundBlacklist(false);
Felipe Leme3d3308d2016-08-23 17:41:47 -0700637 }
638
639 /**
640 * Adds blacklist when restrict background is off - app should receive an intent.
641 */
642 @Test
643 public void testAddRestrictBackgroundBlacklist_restrictBackgroundOff() throws Exception {
644 assertRestrictBackgroundOff(); // Sanity check.
645 addRestrictBackgroundBlacklist(true);
646 }
647
648 private void addRestrictBackgroundBlacklist(boolean expectIntent) throws Exception {
649 assertUidPolicy(UID_A, POLICY_NONE); // Sanity check.
650 final FutureIntent futureIntent = newRestrictBackgroundChangedFuture();
Felipe Leme0ecfcd12016-09-06 12:49:48 -0700651 mPolicyListener.expect().onUidPoliciesChanged(anyInt(), anyInt());
Felipe Leme3d3308d2016-08-23 17:41:47 -0700652
653 mService.setUidPolicy(UID_A, POLICY_REJECT_METERED_BACKGROUND);
654
655 assertUidPolicy(UID_A, POLICY_REJECT_METERED_BACKGROUND);
Felipe Leme0ecfcd12016-09-06 12:49:48 -0700656 mPolicyListener.waitAndVerify()
657 .onUidPoliciesChanged(APP_ID_A, POLICY_REJECT_METERED_BACKGROUND);
Felipe Leme3d3308d2016-08-23 17:41:47 -0700658 if (expectIntent) {
659 assertRestrictBackgroundChangedReceived(futureIntent, PKG_NAME_A);
660 } else {
661 futureIntent.assertNotReceived();
662 }
663 }
664
665 /**
Felipe Leme57e3d312016-08-23 14:42:52 -0700666 * Removes blacklist when restrict background is on - app should not receive an intent.
Felipe Leme3d3308d2016-08-23 17:41:47 -0700667 */
668 @Test
669 @NetPolicyXml("uidA-blacklisted-restrict-background-on.xml")
670 public void testRemoveRestrictBackgroundBlacklist_restrictBackgroundOn() throws Exception {
671 assertRestrictBackgroundOn(); // Sanity check.
Sudheer Shankaed25ce62017-03-29 20:46:30 -0700672 assertRestrictBackgroundChangedReceived(mFutureIntent, null);
Felipe Leme57e3d312016-08-23 14:42:52 -0700673 removeRestrictBackgroundBlacklist(false);
Felipe Leme3d3308d2016-08-23 17:41:47 -0700674 }
675
676 /**
677 * Removes blacklist when restrict background is off - app should receive an intent.
678 */
679 @Test
680 @NetPolicyXml("uidA-blacklisted-restrict-background-off.xml")
681 public void testRemoveRestrictBackgroundBlacklist_restrictBackgroundOff() throws Exception {
682 assertRestrictBackgroundOff(); // Sanity check.
683 removeRestrictBackgroundBlacklist(true);
684 }
685
686 private void removeRestrictBackgroundBlacklist(boolean expectIntent) throws Exception {
687 assertUidPolicy(UID_A, POLICY_REJECT_METERED_BACKGROUND); // Sanity check.
688 final FutureIntent futureIntent = newRestrictBackgroundChangedFuture();
Felipe Leme0ecfcd12016-09-06 12:49:48 -0700689 mPolicyListener.expect().onUidPoliciesChanged(anyInt(), anyInt());
Felipe Leme3d3308d2016-08-23 17:41:47 -0700690
691 mService.setUidPolicy(UID_A, POLICY_NONE);
692
693 assertUidPolicy(UID_A, POLICY_NONE);
Felipe Leme0ecfcd12016-09-06 12:49:48 -0700694 mPolicyListener.waitAndVerify()
695 .onUidPoliciesChanged(APP_ID_A, POLICY_NONE);
Felipe Leme3d3308d2016-08-23 17:41:47 -0700696 if (expectIntent) {
697 assertRestrictBackgroundChangedReceived(futureIntent, PKG_NAME_A);
698 } else {
699 futureIntent.assertNotReceived();
700 }
701 }
702
Felipe Leme51a63642016-08-30 12:15:09 -0700703 @Test
Felipe Lemec08ecdf2016-08-30 12:57:35 -0700704 @NetPolicyXml("uidA-blacklisted-restrict-background-on.xml")
Felipe Leme3d3308d2016-08-23 17:41:47 -0700705 public void testBlacklistedAppIsNotNotifiedWhenRestrictBackgroundIsOn() throws Exception {
706 // Sanity checks.
707 assertRestrictBackgroundOn();
Sudheer Shankaed25ce62017-03-29 20:46:30 -0700708 assertRestrictBackgroundChangedReceived(mFutureIntent, null);
Felipe Leme3d3308d2016-08-23 17:41:47 -0700709 assertUidPolicy(UID_A, POLICY_REJECT_METERED_BACKGROUND);
710
711 final FutureIntent futureIntent = newRestrictBackgroundChangedFuture();
712 setRestrictBackground(true);
713 futureIntent.assertNotReceived();
714 }
715
Felipe Leme51a63642016-08-30 12:15:09 -0700716 @Test
Felipe Lemec08ecdf2016-08-30 12:57:35 -0700717 @NetPolicyXml("uidA-whitelisted-restrict-background-on.xml")
Felipe Leme3d3308d2016-08-23 17:41:47 -0700718 public void testWhitelistedAppIsNotNotifiedWhenRestrictBackgroundIsOn() throws Exception {
719 // Sanity checks.
Felipe Lemec08ecdf2016-08-30 12:57:35 -0700720 assertRestrictBackgroundOn();
Sudheer Shankaed25ce62017-03-29 20:46:30 -0700721 assertRestrictBackgroundChangedReceived(mFutureIntent, null);
Felipe Leme3d3308d2016-08-23 17:41:47 -0700722 assertWhitelistUids(UID_A);
723
724 final FutureIntent futureIntent = newRestrictBackgroundChangedFuture();
725 setRestrictBackground(true);
726 futureIntent.assertNotReceived();
727 }
728
Andreas Gampe84d156b2016-09-03 10:50:38 -0700729 @Test
Felipe Leme57e3d312016-08-23 14:42:52 -0700730 @NetPolicyXml("uidA-whitelisted-restrict-background-on.xml")
731 public void testWhitelistedAppIsNotifiedWhenBlacklisted() throws Exception {
732 // Sanity checks.
733 assertRestrictBackgroundOn();
Sudheer Shankaed25ce62017-03-29 20:46:30 -0700734 assertRestrictBackgroundChangedReceived(mFutureIntent, null);
Felipe Leme57e3d312016-08-23 14:42:52 -0700735 assertWhitelistUids(UID_A);
736
737 final FutureIntent futureIntent = newRestrictBackgroundChangedFuture();
738 mService.setUidPolicy(UID_A, POLICY_REJECT_METERED_BACKGROUND);
739 assertRestrictBackgroundChangedReceived(futureIntent, PKG_NAME_A);
740 }
741
Felipe Leme3d3308d2016-08-23 17:41:47 -0700742 @Test
Felipe Lemee88729d2016-08-17 16:43:01 -0700743 @NetPolicyXml("restrict-background-lists-whitelist-format.xml")
744 public void testRestrictBackgroundLists_whitelistFormat() throws Exception {
Felipe Leme46b451f2016-08-19 08:46:17 -0700745 restrictBackgroundListsTest();
746 }
747
748 @Test
749 @NetPolicyXml("restrict-background-lists-uid-policy-format.xml")
750 public void testRestrictBackgroundLists_uidPolicyFormat() throws Exception {
751 restrictBackgroundListsTest();
752 }
753
754 private void restrictBackgroundListsTest() throws Exception {
Felipe Leme8546a442016-08-23 09:38:20 -0700755 // UIds that are whitelisted.
Felipe Leme46b451f2016-08-19 08:46:17 -0700756 assertWhitelistUids(UID_A, UID_B, UID_C);
757 assertUidPolicy(UID_A, POLICY_ALLOW_METERED_BACKGROUND);
758 assertUidPolicy(UID_B, POLICY_ALLOW_METERED_BACKGROUND);
759 assertUidPolicy(UID_C, POLICY_ALLOW_METERED_BACKGROUND);
Felipe Lemee88729d2016-08-17 16:43:01 -0700760
Felipe Leme8546a442016-08-23 09:38:20 -0700761 // UIDs that are blacklisted.
Felipe Lemee88729d2016-08-17 16:43:01 -0700762 assertUidPolicy(UID_D, POLICY_NONE);
763 assertUidPolicy(UID_E, POLICY_REJECT_METERED_BACKGROUND);
Felipe Leme8546a442016-08-23 09:38:20 -0700764
765 // UIDS that have legacy policies.
Felipe Leme46b451f2016-08-19 08:46:17 -0700766 assertUidPolicy(UID_F, 2); // POLICY_ALLOW_BACKGROUND_BATTERY_SAVE
767
768 // Remove whitelist.
Felipe Leme57e3d312016-08-23 14:42:52 -0700769 mService.setUidPolicy(UID_A, POLICY_NONE);
Felipe Leme46b451f2016-08-19 08:46:17 -0700770 assertUidPolicy(UID_A, POLICY_NONE);
771 assertWhitelistUids(UID_B, UID_C);
772
773 // Add whitelist when blacklisted.
Felipe Leme57e3d312016-08-23 14:42:52 -0700774 mService.setUidPolicy(UID_E, POLICY_ALLOW_METERED_BACKGROUND);
Felipe Leme46b451f2016-08-19 08:46:17 -0700775 assertUidPolicy(UID_E, POLICY_ALLOW_METERED_BACKGROUND);
776 assertWhitelistUids(UID_B, UID_C, UID_E);
777
778 // Add blacklist when whitelisted.
779 mService.setUidPolicy(UID_B, POLICY_REJECT_METERED_BACKGROUND);
780 assertUidPolicy(UID_B, POLICY_REJECT_METERED_BACKGROUND);
781 assertWhitelistUids(UID_C, UID_E);
782 }
783
784 /**
785 * Tests scenario where an UID had {@code restrict-background} and {@code uid-policy} tags.
786 */
787 @Test
788 @NetPolicyXml("restrict-background-lists-mixed-format.xml")
789 public void testRestrictBackgroundLists_mixedFormat() throws Exception {
790 assertWhitelistUids(UID_A, UID_C, UID_D);
791 assertUidPolicy(UID_A, POLICY_ALLOW_METERED_BACKGROUND);
Felipe Leme57e3d312016-08-23 14:42:52 -0700792 assertUidPolicy(UID_B, POLICY_REJECT_METERED_BACKGROUND); // Blacklist prevails.
Felipe Leme46b451f2016-08-19 08:46:17 -0700793 assertUidPolicy(UID_C, (POLICY_ALLOW_METERED_BACKGROUND | 2));
794 assertUidPolicy(UID_D, POLICY_ALLOW_METERED_BACKGROUND);
Felipe Lemee88729d2016-08-17 16:43:01 -0700795 }
796
Felipe Leme6f51a0a2016-08-24 15:11:51 -0700797 @Test
798 @NetPolicyXml("uids-with-mixed-policies.xml")
799 public void testGetUidsWithPolicy() throws Exception {
Felipe Leme03f90292016-09-08 18:10:32 -0700800 assertContainsInAnyOrder(mService.getUidsWithPolicy(POLICY_NONE));
Felipe Leme6f51a0a2016-08-24 15:11:51 -0700801 assertContainsInAnyOrder(mService.getUidsWithPolicy(POLICY_REJECT_METERED_BACKGROUND),
802 UID_B, UID_D);
803 assertContainsInAnyOrder(mService.getUidsWithPolicy(POLICY_ALLOW_METERED_BACKGROUND),
804 UID_E, UID_F);
805 // Legacy (POLICY_ALLOW_BACKGROUND_BATTERY_SAVE)
806 assertContainsInAnyOrder(mService.getUidsWithPolicy(2),
807 UID_C, UID_D, UID_F);
808 }
809
Felipe Leme0ecfcd12016-09-06 12:49:48 -0700810 // NOTE: testPolicyChangeTriggersListener() is too superficial, they
Felipe Lemeef134662016-08-10 14:46:39 -0700811 // don't check for side-effects (like calls to NetworkManagementService) neither cover all
812 // different modes (Data Saver, Battery Saver, Doze, App idle, etc...).
813 // These scenarios are extensively tested on CTS' HostsideRestrictBackgroundNetworkTests.
Felipe Leme9f27e7a2016-08-12 15:19:40 -0700814 @Test
Felipe Lemeef134662016-08-10 14:46:39 -0700815 public void testUidForeground() throws Exception {
816 // push all uids into background
Sudheer Shankaed25ce62017-03-29 20:46:30 -0700817 callOnUidStateChanged(UID_A, ActivityManager.PROCESS_STATE_SERVICE, 0);
818 callOnUidStateChanged(UID_B, ActivityManager.PROCESS_STATE_SERVICE, 0);
Jeff Sharkey9599cc52011-05-22 14:59:31 -0700819 assertFalse(mService.isUidForeground(UID_A));
820 assertFalse(mService.isUidForeground(UID_B));
821
Felipe Lemeef134662016-08-10 14:46:39 -0700822 // push one of the uids into foreground
Sudheer Shankaed25ce62017-03-29 20:46:30 -0700823 callOnUidStateChanged(UID_A, ActivityManager.PROCESS_STATE_TOP, 0);
Jeff Sharkey9599cc52011-05-22 14:59:31 -0700824 assertTrue(mService.isUidForeground(UID_A));
825 assertFalse(mService.isUidForeground(UID_B));
826
827 // and swap another uid into foreground
Sudheer Shankaed25ce62017-03-29 20:46:30 -0700828 callOnUidStateChanged(UID_A, ActivityManager.PROCESS_STATE_SERVICE, 0);
829 callOnUidStateChanged(UID_B, ActivityManager.PROCESS_STATE_TOP, 0);
Jeff Sharkey9599cc52011-05-22 14:59:31 -0700830 assertFalse(mService.isUidForeground(UID_A));
831 assertTrue(mService.isUidForeground(UID_B));
Jeff Sharkey9599cc52011-05-22 14:59:31 -0700832 }
833
Jeff Sharkey53313d72017-07-13 16:47:32 -0600834 private static long computeLastCycleBoundary(long currentTime, NetworkPolicy policy) {
Jeff Sharkey17bebd22017-07-19 21:00:38 -0600835 RecurrenceRule.sClock = Clock.fixed(Instant.ofEpochMilli(currentTime),
836 ZoneId.systemDefault());
Jeff Sharkey0fc6d032018-03-30 16:25:11 -0600837 final Iterator<Range<ZonedDateTime>> it = policy.cycleIterator();
Jeff Sharkey53313d72017-07-13 16:47:32 -0600838 while (it.hasNext()) {
Jeff Sharkey0fc6d032018-03-30 16:25:11 -0600839 final Range<ZonedDateTime> cycle = it.next();
840 if (cycle.getLower().toInstant().toEpochMilli() < currentTime) {
841 return cycle.getLower().toInstant().toEpochMilli();
Jeff Sharkey53313d72017-07-13 16:47:32 -0600842 }
843 }
844 throw new IllegalStateException(
845 "Failed to find current cycle for " + policy + " at " + currentTime);
846 }
847
848 private static long computeNextCycleBoundary(long currentTime, NetworkPolicy policy) {
Jeff Sharkey17bebd22017-07-19 21:00:38 -0600849 RecurrenceRule.sClock = Clock.fixed(Instant.ofEpochMilli(currentTime),
850 ZoneId.systemDefault());
Jeff Sharkey0fc6d032018-03-30 16:25:11 -0600851 return policy.cycleIterator().next().getUpper().toInstant().toEpochMilli();
Jeff Sharkey53313d72017-07-13 16:47:32 -0600852 }
853
Felipe Leme9f27e7a2016-08-12 15:19:40 -0700854 @Test
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700855 public void testLastCycleBoundaryThisMonth() throws Exception {
856 // assume cycle day of "5th", which should be in same month
857 final long currentTime = parseTime("2007-11-14T00:00:00.000Z");
858 final long expectedCycle = parseTime("2007-11-05T00:00:00.000Z");
859
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -0700860 final NetworkPolicy policy = new NetworkPolicy(
Jeff Sharkey9bf31502012-03-09 17:07:21 -0800861 sTemplateWifi, 5, TIMEZONE_UTC, 1024L, 1024L, false);
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700862 final long actualCycle = computeLastCycleBoundary(currentTime, policy);
Jeff Sharkeyaf82ea22011-08-04 15:38:48 -0700863 assertTimeEquals(expectedCycle, actualCycle);
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700864 }
865
Felipe Leme9f27e7a2016-08-12 15:19:40 -0700866 @Test
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700867 public void testLastCycleBoundaryLastMonth() throws Exception {
868 // assume cycle day of "20th", which should be in last month
869 final long currentTime = parseTime("2007-11-14T00:00:00.000Z");
870 final long expectedCycle = parseTime("2007-10-20T00:00:00.000Z");
871
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -0700872 final NetworkPolicy policy = new NetworkPolicy(
Jeff Sharkey9bf31502012-03-09 17:07:21 -0800873 sTemplateWifi, 20, TIMEZONE_UTC, 1024L, 1024L, false);
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700874 final long actualCycle = computeLastCycleBoundary(currentTime, policy);
Jeff Sharkeyaf82ea22011-08-04 15:38:48 -0700875 assertTimeEquals(expectedCycle, actualCycle);
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700876 }
877
Felipe Leme9f27e7a2016-08-12 15:19:40 -0700878 @Test
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700879 public void testLastCycleBoundaryThisMonthFebruary() throws Exception {
880 // assume cycle day of "30th" in february; should go to january
881 final long currentTime = parseTime("2007-02-14T00:00:00.000Z");
882 final long expectedCycle = parseTime("2007-01-30T00:00:00.000Z");
883
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -0700884 final NetworkPolicy policy = new NetworkPolicy(
Jeff Sharkey9bf31502012-03-09 17:07:21 -0800885 sTemplateWifi, 30, TIMEZONE_UTC, 1024L, 1024L, false);
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700886 final long actualCycle = computeLastCycleBoundary(currentTime, policy);
Jeff Sharkeyaf82ea22011-08-04 15:38:48 -0700887 assertTimeEquals(expectedCycle, actualCycle);
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700888 }
889
Felipe Leme9f27e7a2016-08-12 15:19:40 -0700890 @Test
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700891 public void testLastCycleBoundaryLastMonthFebruary() throws Exception {
892 // assume cycle day of "30th" in february, which should clamp
893 final long currentTime = parseTime("2007-03-14T00:00:00.000Z");
Jeff Sharkey53313d72017-07-13 16:47:32 -0600894 final long expectedCycle = parseTime("2007-02-28T23:59:59.999Z");
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700895
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -0700896 final NetworkPolicy policy = new NetworkPolicy(
Jeff Sharkey9bf31502012-03-09 17:07:21 -0800897 sTemplateWifi, 30, TIMEZONE_UTC, 1024L, 1024L, false);
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700898 final long actualCycle = computeLastCycleBoundary(currentTime, policy);
Jeff Sharkeyaf82ea22011-08-04 15:38:48 -0700899 assertTimeEquals(expectedCycle, actualCycle);
900 }
901
Felipe Leme9f27e7a2016-08-12 15:19:40 -0700902 @Test
Jeff Sharkey9bf31502012-03-09 17:07:21 -0800903 public void testCycleBoundaryLeapYear() throws Exception {
904 final NetworkPolicy policy = new NetworkPolicy(
905 sTemplateWifi, 29, TIMEZONE_UTC, 1024L, 1024L, false);
906
907 assertTimeEquals(parseTime("2012-01-29T00:00:00.000Z"),
908 computeNextCycleBoundary(parseTime("2012-01-14T00:00:00.000Z"), policy));
909 assertTimeEquals(parseTime("2012-02-29T00:00:00.000Z"),
910 computeNextCycleBoundary(parseTime("2012-02-14T00:00:00.000Z"), policy));
911 assertTimeEquals(parseTime("2012-02-29T00:00:00.000Z"),
912 computeLastCycleBoundary(parseTime("2012-03-14T00:00:00.000Z"), policy));
913 assertTimeEquals(parseTime("2012-03-29T00:00:00.000Z"),
914 computeNextCycleBoundary(parseTime("2012-03-14T00:00:00.000Z"), policy));
915
916 assertTimeEquals(parseTime("2007-01-29T00:00:00.000Z"),
917 computeNextCycleBoundary(parseTime("2007-01-14T00:00:00.000Z"), policy));
Jeff Sharkey53313d72017-07-13 16:47:32 -0600918 assertTimeEquals(parseTime("2007-02-28T23:59:59.999Z"),
Jeff Sharkey9bf31502012-03-09 17:07:21 -0800919 computeNextCycleBoundary(parseTime("2007-02-14T00:00:00.000Z"), policy));
Jeff Sharkey53313d72017-07-13 16:47:32 -0600920 assertTimeEquals(parseTime("2007-02-28T23:59:59.999Z"),
Jeff Sharkey9bf31502012-03-09 17:07:21 -0800921 computeLastCycleBoundary(parseTime("2007-03-14T00:00:00.000Z"), policy));
922 assertTimeEquals(parseTime("2007-03-29T00:00:00.000Z"),
923 computeNextCycleBoundary(parseTime("2007-03-14T00:00:00.000Z"), policy));
924 }
925
Felipe Leme9f27e7a2016-08-12 15:19:40 -0700926 @Test
Jeff Sharkey9bf31502012-03-09 17:07:21 -0800927 public void testNextCycleTimezoneAfterUtc() throws Exception {
928 // US/Central is UTC-6
929 final NetworkPolicy policy = new NetworkPolicy(
930 sTemplateWifi, 10, "US/Central", 1024L, 1024L, false);
931 assertTimeEquals(parseTime("2012-01-10T06:00:00.000Z"),
932 computeNextCycleBoundary(parseTime("2012-01-05T00:00:00.000Z"), policy));
933 }
934
Felipe Leme9f27e7a2016-08-12 15:19:40 -0700935 @Test
Jeff Sharkey9bf31502012-03-09 17:07:21 -0800936 public void testNextCycleTimezoneBeforeUtc() throws Exception {
937 // Israel is UTC+2
938 final NetworkPolicy policy = new NetworkPolicy(
939 sTemplateWifi, 10, "Israel", 1024L, 1024L, false);
940 assertTimeEquals(parseTime("2012-01-09T22:00:00.000Z"),
941 computeNextCycleBoundary(parseTime("2012-01-05T00:00:00.000Z"), policy));
942 }
943
Felipe Leme9f27e7a2016-08-12 15:19:40 -0700944 @Test
Jeff Sharkey15399052013-01-15 14:15:53 -0800945 public void testCycleTodayJanuary() throws Exception {
946 final NetworkPolicy policy = new NetworkPolicy(
947 sTemplateWifi, 14, "US/Pacific", 1024L, 1024L, false);
948
949 assertTimeEquals(parseTime("2013-01-14T00:00:00.000-08:00"),
950 computeNextCycleBoundary(parseTime("2013-01-13T23:59:59.000-08:00"), policy));
951 assertTimeEquals(parseTime("2013-02-14T00:00:00.000-08:00"),
952 computeNextCycleBoundary(parseTime("2013-01-14T00:00:01.000-08:00"), policy));
953 assertTimeEquals(parseTime("2013-02-14T00:00:00.000-08:00"),
954 computeNextCycleBoundary(parseTime("2013-01-14T15:11:00.000-08:00"), policy));
955
956 assertTimeEquals(parseTime("2012-12-14T00:00:00.000-08:00"),
957 computeLastCycleBoundary(parseTime("2013-01-13T23:59:59.000-08:00"), policy));
958 assertTimeEquals(parseTime("2013-01-14T00:00:00.000-08:00"),
959 computeLastCycleBoundary(parseTime("2013-01-14T00:00:01.000-08:00"), policy));
960 assertTimeEquals(parseTime("2013-01-14T00:00:00.000-08:00"),
961 computeLastCycleBoundary(parseTime("2013-01-14T15:11:00.000-08:00"), policy));
962 }
963
Felipe Leme9f27e7a2016-08-12 15:19:40 -0700964 @Test
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700965 public void testNetworkPolicyAppliedCycleLastMonth() throws Exception {
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700966 NetworkState[] state = null;
967 NetworkStats stats = null;
968
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700969 final int CYCLE_DAY = 15;
Jeff Sharkey53313d72017-07-13 16:47:32 -0600970 final long NOW = parseTime("2007-03-10T00:00Z");
971 final long CYCLE_START = parseTime("2007-02-15T00:00Z");
972 final long CYCLE_END = parseTime("2007-03-15T00:00Z");
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700973
Jeff Sharkey53313d72017-07-13 16:47:32 -0600974 setCurrentTimeMillis(NOW);
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -0700975
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700976 // first, pretend that wifi network comes online. no policy active,
977 // which means we shouldn't push limit to interface.
978 state = new NetworkState[] { buildWifi() };
Felipe Lemeef134662016-08-10 14:46:39 -0700979 when(mConnManager.getAllNetworkState()).thenReturn(state);
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700980
Felipe Lemeef134662016-08-10 14:46:39 -0700981 mPolicyListener.expect().onMeteredIfacesChanged(any());
Erik Klinef851d6d2015-04-20 16:03:48 +0900982 mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION));
Felipe Lemeef134662016-08-10 14:46:39 -0700983 mPolicyListener.waitAndVerify().onMeteredIfacesChanged(any());
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700984
985 // now change cycle to be on 15th, and test in early march, to verify we
986 // pick cycle day in previous month.
Felipe Lemeef134662016-08-10 14:46:39 -0700987 when(mConnManager.getAllNetworkState()).thenReturn(state);
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700988
989 // pretend that 512 bytes total have happened
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -0700990 stats = new NetworkStats(getElapsedRealtime(), 1)
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -0700991 .addIfaceValues(TEST_IFACE, 256L, 2L, 256L, 2L);
Jeff Sharkey53313d72017-07-13 16:47:32 -0600992 when(mStatsService.getNetworkTotalBytes(sTemplateWifi, CYCLE_START, CYCLE_END))
Felipe Lemeef134662016-08-10 14:46:39 -0700993 .thenReturn(stats.getTotalBytes());
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700994
Felipe Lemeef134662016-08-10 14:46:39 -0700995 mPolicyListener.expect().onMeteredIfacesChanged(any());
Jeff Sharkey163e6442011-10-31 16:37:52 -0700996 setNetworkPolicies(new NetworkPolicy(
Jeff Sharkey9bf31502012-03-09 17:07:21 -0800997 sTemplateWifi, CYCLE_DAY, TIMEZONE_UTC, 1 * MB_IN_BYTES, 2 * MB_IN_BYTES, false));
Felipe Lemeef134662016-08-10 14:46:39 -0700998 mPolicyListener.waitAndVerify().onMeteredIfacesChanged(eq(new String[]{TEST_IFACE}));
999
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001000 verify(mNetworkManager, atLeastOnce()).setInterfaceQuota(TEST_IFACE,
1001 (2 * MB_IN_BYTES) - 512);
Jeff Sharkey21c9c452011-06-07 12:26:43 -07001002 }
1003
Felipe Leme9f27e7a2016-08-12 15:19:40 -07001004 @Test
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001005 public void testNotificationWarningLimitSnooze() throws Exception {
Jeff Sharkey2e471452018-01-19 18:02:47 +09001006 // Create a place to store fake usage
1007 final NetworkStatsHistory history = new NetworkStatsHistory(TimeUnit.HOURS.toMillis(1));
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001008 final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 0);
Jeff Sharkey2e471452018-01-19 18:02:47 +09001009 when(mStatsService.getNetworkTotalBytes(any(), anyLong(), anyLong()))
1010 .thenAnswer(new Answer<Long>() {
1011 @Override
1012 public Long answer(InvocationOnMock invocation) throws Throwable {
1013 final NetworkStatsHistory.Entry entry = history.getValues(
1014 invocation.getArgument(1), invocation.getArgument(2), null);
1015 return entry.rxBytes + entry.txBytes;
1016 }
1017 });
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001018 when(mStatsService.getNetworkUidBytes(any(), anyLong(), anyLong()))
1019 .thenAnswer(new Answer<NetworkStats>() {
1020 @Override
1021 public NetworkStats answer(InvocationOnMock invocation) throws Throwable {
1022 return stats;
1023 }
1024 });
Jeff Sharkey2e471452018-01-19 18:02:47 +09001025
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001026 // Get active mobile network in place
1027 expectMobileDefaults();
1028 mService.updateNetworks();
1029
1030 // Define simple data plan
Remi NGUYEN VANed6d2ca2018-04-04 11:12:51 +09001031 final SubscriptionPlan plan = buildMonthlyDataPlan(
1032 ZonedDateTime.parse("2015-11-01T00:00:00.00Z"), DataUnit.MEGABYTES.toBytes(1800));
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001033 mService.setSubscriptionPlans(TEST_SUB_ID, new SubscriptionPlan[] { plan },
Jeff Sharkey2e471452018-01-19 18:02:47 +09001034 mServiceContext.getOpPackageName());
1035
Jeff Sharkey2e471452018-01-19 18:02:47 +09001036 // We're 20% through the month (6 days)
1037 final long start = parseTime("2015-11-01T00:00Z");
1038 final long end = parseTime("2015-11-07T00:00Z");
1039 setCurrentTimeMillis(end);
1040
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001041 // Normal usage means no notification
1042 {
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001043 history.clear();
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001044 history.recordData(start, end,
1045 new NetworkStats.Entry(DataUnit.MEGABYTES.toBytes(360), 0L, 0L, 0L, 0));
1046
1047 reset(mTelephonyManager, mNetworkManager, mNotifManager);
1048 expectMobileDefaults();
1049
1050 mService.updateNetworks();
1051
1052 verify(mTelephonyManager, atLeastOnce()).setPolicyDataEnabled(true, TEST_SUB_ID);
1053 verify(mNetworkManager, atLeastOnce()).setInterfaceQuota(TEST_IFACE,
1054 DataUnit.MEGABYTES.toBytes(1800 - 360));
1055 verify(mNotifManager, never()).notifyAsUser(any(), anyInt(), any(), any());
1056 }
1057
1058 // Push over warning
1059 {
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001060 history.clear();
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001061 history.recordData(start, end,
1062 new NetworkStats.Entry(DataUnit.MEGABYTES.toBytes(1799), 0L, 0L, 0L, 0));
1063
1064 reset(mTelephonyManager, mNetworkManager, mNotifManager);
1065 expectMobileDefaults();
1066
1067 mService.updateNetworks();
1068
1069 verify(mTelephonyManager, atLeastOnce()).setPolicyDataEnabled(true, TEST_SUB_ID);
1070 verify(mNetworkManager, atLeastOnce()).setInterfaceQuota(TEST_IFACE,
1071 DataUnit.MEGABYTES.toBytes(1800 - 1799));
1072 verify(mNotifManager, atLeastOnce()).notifyAsUser(any(), eq(TYPE_WARNING),
1073 isA(Notification.class), eq(UserHandle.ALL));
1074 }
1075
1076 // Push over limit
1077 {
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001078 history.clear();
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001079 history.recordData(start, end,
1080 new NetworkStats.Entry(DataUnit.MEGABYTES.toBytes(1810), 0L, 0L, 0L, 0));
1081
1082 reset(mTelephonyManager, mNetworkManager, mNotifManager);
1083 expectMobileDefaults();
1084
1085 mService.updateNetworks();
1086
1087 verify(mTelephonyManager, atLeastOnce()).setPolicyDataEnabled(false, TEST_SUB_ID);
1088 verify(mNetworkManager, atLeastOnce()).setInterfaceQuota(TEST_IFACE, 1);
1089 verify(mNotifManager, atLeastOnce()).notifyAsUser(any(), eq(TYPE_LIMIT),
1090 isA(Notification.class), eq(UserHandle.ALL));
1091 }
1092
1093 // Snooze limit
1094 {
1095 reset(mTelephonyManager, mNetworkManager, mNotifManager);
1096 expectMobileDefaults();
1097
1098 mService.snoozeLimit(NetworkTemplate.buildTemplateMobileAll(TEST_IMSI));
1099 mService.updateNetworks();
1100
1101 verify(mTelephonyManager, atLeastOnce()).setPolicyDataEnabled(true, TEST_SUB_ID);
1102 verify(mNetworkManager, atLeastOnce()).setInterfaceQuota(TEST_IFACE,
1103 Long.MAX_VALUE);
1104 verify(mNotifManager, atLeastOnce()).notifyAsUser(any(), eq(TYPE_LIMIT_SNOOZED),
1105 isA(Notification.class), eq(UserHandle.ALL));
1106 }
1107 }
1108
1109 @Test
1110 public void testNotificationRapid() throws Exception {
1111 // Create a place to store fake usage
1112 final NetworkStatsHistory history = new NetworkStatsHistory(TimeUnit.HOURS.toMillis(1));
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001113 final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 0);
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001114 when(mStatsService.getNetworkTotalBytes(any(), anyLong(), anyLong()))
1115 .thenAnswer(new Answer<Long>() {
1116 @Override
1117 public Long answer(InvocationOnMock invocation) throws Throwable {
1118 final NetworkStatsHistory.Entry entry = history.getValues(
1119 invocation.getArgument(1), invocation.getArgument(2), null);
1120 return entry.rxBytes + entry.txBytes;
1121 }
1122 });
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001123 when(mStatsService.getNetworkUidBytes(any(), anyLong(), anyLong()))
1124 .thenAnswer(new Answer<NetworkStats>() {
1125 @Override
1126 public NetworkStats answer(InvocationOnMock invocation) throws Throwable {
1127 return stats;
1128 }
1129 });
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001130
1131 // Get active mobile network in place
1132 expectMobileDefaults();
1133 mService.updateNetworks();
1134
1135 // Define simple data plan which gives us effectively 60MB/day
Remi NGUYEN VANed6d2ca2018-04-04 11:12:51 +09001136 final SubscriptionPlan plan = buildMonthlyDataPlan(
1137 ZonedDateTime.parse("2015-11-01T00:00:00.00Z"), DataUnit.MEGABYTES.toBytes(1800));
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001138 mService.setSubscriptionPlans(TEST_SUB_ID, new SubscriptionPlan[] { plan },
1139 mServiceContext.getOpPackageName());
1140
1141 // We're 20% through the month (6 days)
1142 final long start = parseTime("2015-11-01T00:00Z");
1143 final long end = parseTime("2015-11-07T00:00Z");
1144 setCurrentTimeMillis(end);
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001145
1146 // Using 20% data in 20% time is normal
Jeff Sharkey2e471452018-01-19 18:02:47 +09001147 {
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001148 history.clear();
Jeff Sharkey2e471452018-01-19 18:02:47 +09001149 history.recordData(start, end,
1150 new NetworkStats.Entry(DataUnit.MEGABYTES.toBytes(360), 0L, 0L, 0L, 0));
1151
1152 reset(mNotifManager);
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001153 mService.updateNetworks();
1154 verify(mNotifManager, never()).notifyAsUser(any(), anyInt(), any(), any());
Jeff Sharkey2e471452018-01-19 18:02:47 +09001155 }
1156
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001157 // Using 80% data in 20% time is alarming; but spread equally among
1158 // three UIDs means we get generic alert
Jeff Sharkey2e471452018-01-19 18:02:47 +09001159 {
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001160 history.clear();
Jeff Sharkey2e471452018-01-19 18:02:47 +09001161 history.recordData(start, end,
1162 new NetworkStats.Entry(DataUnit.MEGABYTES.toBytes(1440), 0L, 0L, 0L, 0));
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001163 stats.clear();
1164 stats.addValues(IFACE_ALL, UID_A, SET_ALL, TAG_ALL,
1165 DataUnit.MEGABYTES.toBytes(480), 0, 0, 0, 0);
1166 stats.addValues(IFACE_ALL, UID_B, SET_ALL, TAG_ALL,
1167 DataUnit.MEGABYTES.toBytes(480), 0, 0, 0, 0);
1168 stats.addValues(IFACE_ALL, UID_C, SET_ALL, TAG_ALL,
1169 DataUnit.MEGABYTES.toBytes(480), 0, 0, 0, 0);
Jeff Sharkey2e471452018-01-19 18:02:47 +09001170
1171 reset(mNotifManager);
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001172 mService.updateNetworks();
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001173
1174 final ArgumentCaptor<Notification> notif = ArgumentCaptor.forClass(Notification.class);
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001175 verify(mNotifManager, atLeastOnce()).notifyAsUser(any(), eq(TYPE_RAPID),
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001176 notif.capture(), eq(UserHandle.ALL));
1177
1178 final String text = notif.getValue().extras.getCharSequence(Notification.EXTRA_TEXT)
1179 .toString();
1180 assertFalse(text.contains(PKG_NAME_A));
1181 assertFalse(text.contains(PKG_NAME_B));
1182 assertFalse(text.contains(PKG_NAME_C));
1183 }
1184
1185 // Using 80% data in 20% time is alarming; but mostly done by one UID
1186 // means we get specific alert
1187 {
1188 history.clear();
1189 history.recordData(start, end,
1190 new NetworkStats.Entry(DataUnit.MEGABYTES.toBytes(1440), 0L, 0L, 0L, 0));
1191 stats.clear();
1192 stats.addValues(IFACE_ALL, UID_A, SET_ALL, TAG_ALL,
1193 DataUnit.MEGABYTES.toBytes(960), 0, 0, 0, 0);
1194 stats.addValues(IFACE_ALL, UID_B, SET_ALL, TAG_ALL,
1195 DataUnit.MEGABYTES.toBytes(480), 0, 0, 0, 0);
1196
1197 reset(mNotifManager);
1198 mService.updateNetworks();
1199
1200 final ArgumentCaptor<Notification> notif = ArgumentCaptor.forClass(Notification.class);
1201 verify(mNotifManager, atLeastOnce()).notifyAsUser(any(), eq(TYPE_RAPID),
1202 notif.capture(), eq(UserHandle.ALL));
1203
1204 final String text = notif.getValue().extras.getCharSequence(Notification.EXTRA_TEXT)
1205 .toString();
1206 assertTrue(text.contains(PKG_NAME_A));
1207 assertFalse(text.contains(PKG_NAME_B));
1208 assertFalse(text.contains(PKG_NAME_C));
Jeff Sharkey2e471452018-01-19 18:02:47 +09001209 }
1210 }
1211
1212 @Test
Jeff Sharkeyf60d0af2011-11-30 15:28:02 -08001213 public void testMeteredNetworkWithoutLimit() throws Exception {
1214 NetworkState[] state = null;
1215 NetworkStats stats = null;
Jeff Sharkeyf60d0af2011-11-30 15:28:02 -08001216
1217 final long TIME_FEB_15 = 1171497600000L;
1218 final long TIME_MAR_10 = 1173484800000L;
1219 final int CYCLE_DAY = 15;
1220
1221 setCurrentTimeMillis(TIME_MAR_10);
1222
1223 // bring up wifi network with metered policy
1224 state = new NetworkState[] { buildWifi() };
1225 stats = new NetworkStats(getElapsedRealtime(), 1)
1226 .addIfaceValues(TEST_IFACE, 0L, 0L, 0L, 0L);
1227
1228 {
Felipe Lemeef134662016-08-10 14:46:39 -07001229 when(mConnManager.getAllNetworkState()).thenReturn(state);
1230 when(mStatsService.getNetworkTotalBytes(sTemplateWifi, TIME_FEB_15,
1231 currentTimeMillis())).thenReturn(stats.getTotalBytes());
Jeff Sharkeyf60d0af2011-11-30 15:28:02 -08001232
Felipe Lemeef134662016-08-10 14:46:39 -07001233 mPolicyListener.expect().onMeteredIfacesChanged(any());
Jeff Sharkey9bf31502012-03-09 17:07:21 -08001234 setNetworkPolicies(new NetworkPolicy(
1235 sTemplateWifi, CYCLE_DAY, TIMEZONE_UTC, WARNING_DISABLED, LIMIT_DISABLED,
1236 true));
Felipe Lemeef134662016-08-10 14:46:39 -07001237 mPolicyListener.waitAndVerify().onMeteredIfacesChanged(eq(new String[]{TEST_IFACE}));
1238
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001239 verify(mNetworkManager, atLeastOnce()).setInterfaceQuota(TEST_IFACE,
1240 Long.MAX_VALUE);
Jeff Sharkeyf60d0af2011-11-30 15:28:02 -08001241 }
1242 }
1243
Sudheer Shankae7361852017-03-07 11:51:46 -08001244 @Test
1245 public void testOnUidStateChanged_notifyAMS() throws Exception {
1246 final long procStateSeq = 222;
Sudheer Shankaed25ce62017-03-29 20:46:30 -07001247 callOnUidStateChanged(UID_A, ActivityManager.PROCESS_STATE_SERVICE, procStateSeq);
Sudheer Shankae7361852017-03-07 11:51:46 -08001248 verify(mActivityManagerInternal).notifyNetworkPolicyRulesUpdated(UID_A, procStateSeq);
Sudheer Shankae7361852017-03-07 11:51:46 -08001249 }
1250
Sudheer Shankaed25ce62017-03-29 20:46:30 -07001251 private void callOnUidStateChanged(int uid, int procState, long procStateSeq)
1252 throws Exception {
1253 mUidObserver.onUidStateChanged(uid, procState, procStateSeq);
1254 final CountDownLatch latch = new CountDownLatch(1);
1255 mService.mUidEventHandler.post(() -> {
1256 latch.countDown();
1257 });
1258 latch.await(2, TimeUnit.SECONDS);
1259 }
1260
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07001261 private void assertCycleDayAsExpected(PersistableBundle config, int carrierCycleDay,
1262 boolean expectValid) {
1263 config.putInt(KEY_MONTHLY_DATA_CYCLE_DAY_INT, carrierCycleDay);
1264 int actualCycleDay = mService.getCycleDayFromCarrierConfig(config,
1265 INVALID_CARRIER_CONFIG_VALUE);
1266 if (expectValid) {
1267 assertEquals(carrierCycleDay, actualCycleDay);
1268 } else {
1269 // INVALID_CARRIER_CONFIG_VALUE is returned for invalid values
1270 assertEquals(INVALID_CARRIER_CONFIG_VALUE, actualCycleDay);
1271 }
1272 }
1273
1274 @Test
1275 public void testGetCycleDayFromCarrierConfig() {
1276 PersistableBundle config = CarrierConfigManager.getDefaultConfig();
1277 final Calendar cal = Calendar.getInstance();
1278 int actualCycleDay;
1279
1280 config.putInt(KEY_MONTHLY_DATA_CYCLE_DAY_INT, DATA_CYCLE_USE_PLATFORM_DEFAULT);
1281 actualCycleDay = mService.getCycleDayFromCarrierConfig(config, DEFAULT_CYCLE_DAY);
1282 assertEquals(DEFAULT_CYCLE_DAY, actualCycleDay);
1283
1284 // null config returns a default value
1285 actualCycleDay = mService.getCycleDayFromCarrierConfig(null, DEFAULT_CYCLE_DAY);
1286 assertEquals(DEFAULT_CYCLE_DAY, actualCycleDay);
1287
1288 // Sane, non-default values
1289 assertCycleDayAsExpected(config, 1, true);
1290 assertCycleDayAsExpected(config, cal.getMaximum(Calendar.DAY_OF_MONTH), true);
1291 assertCycleDayAsExpected(config, cal.getMinimum(Calendar.DAY_OF_MONTH), true);
1292
1293 // Invalid values
1294 assertCycleDayAsExpected(config, 0, false);
1295 assertCycleDayAsExpected(config, DATA_CYCLE_THRESHOLD_DISABLED, false);
1296 assertCycleDayAsExpected(config, cal.getMaximum(Calendar.DAY_OF_MONTH) + 1, false);
1297 assertCycleDayAsExpected(config, cal.getMinimum(Calendar.DAY_OF_MONTH) - 5, false);
1298 }
1299
1300 private void assertWarningBytesAsExpected(PersistableBundle config, long carrierWarningBytes,
1301 long expected) {
1302 config.putLong(KEY_DATA_WARNING_THRESHOLD_BYTES_LONG, carrierWarningBytes);
1303 long actualWarning = mService.getWarningBytesFromCarrierConfig(config,
1304 INVALID_CARRIER_CONFIG_VALUE);
1305 assertEquals(expected, actualWarning);
1306 }
1307
1308 @Test
1309 public void testGetWarningBytesFromCarrierConfig() {
1310 PersistableBundle config = CarrierConfigManager.getDefaultConfig();
1311 long actualWarningBytes;
1312
1313 assertWarningBytesAsExpected(config, DATA_CYCLE_USE_PLATFORM_DEFAULT,
1314 mDefaultWarningBytes);
1315 assertWarningBytesAsExpected(config, DATA_CYCLE_THRESHOLD_DISABLED, WARNING_DISABLED);
1316 assertWarningBytesAsExpected(config, 0, 0);
1317 // not a valid value
1318 assertWarningBytesAsExpected(config, -1000, INVALID_CARRIER_CONFIG_VALUE);
1319
1320 // null config returns a default value
1321 actualWarningBytes = mService.getWarningBytesFromCarrierConfig(null, mDefaultWarningBytes);
1322 assertEquals(mDefaultWarningBytes, actualWarningBytes);
1323 }
1324
1325 private void assertLimitBytesAsExpected(PersistableBundle config, long carrierWarningBytes,
1326 long expected) {
1327 config.putLong(KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG, carrierWarningBytes);
1328 long actualWarning = mService.getLimitBytesFromCarrierConfig(config,
1329 INVALID_CARRIER_CONFIG_VALUE);
1330 assertEquals(expected, actualWarning);
1331 }
1332
1333 @Test
1334 public void testGetLimitBytesFromCarrierConfig() {
1335 PersistableBundle config = CarrierConfigManager.getDefaultConfig();
1336 long actualLimitBytes;
1337
1338 assertLimitBytesAsExpected(config, DATA_CYCLE_USE_PLATFORM_DEFAULT,
1339 mDefaultLimitBytes);
1340 assertLimitBytesAsExpected(config, DATA_CYCLE_THRESHOLD_DISABLED, LIMIT_DISABLED);
1341 assertLimitBytesAsExpected(config, 0, 0);
1342 // not a valid value
1343 assertLimitBytesAsExpected(config, -1000, INVALID_CARRIER_CONFIG_VALUE);
1344
1345 // null config returns a default value
1346 actualLimitBytes = mService.getWarningBytesFromCarrierConfig(null, mDefaultLimitBytes);
1347 assertEquals(mDefaultLimitBytes, actualLimitBytes);
1348 }
1349
1350 private PersistableBundle setupUpdateMobilePolicyCycleTests() throws RemoteException {
1351 when(mConnManager.getAllNetworkState()).thenReturn(new NetworkState[0]);
1352 when(mSubscriptionManager.getActiveSubscriptionIdList()).thenReturn(new int[]{FAKE_SUB_ID});
1353 when(mTelephonyManager.getSubscriberId(FAKE_SUB_ID)).thenReturn(FAKE_SUBSCRIBER_ID);
1354 PersistableBundle bundle = CarrierConfigManager.getDefaultConfig();
1355 when(mCarrierConfigManager.getConfigForSubId(FAKE_SUB_ID)).thenReturn(bundle);
1356 setNetworkPolicies(buildDefaultFakeMobilePolicy());
1357 return bundle;
1358 }
1359
1360 @Test
1361 public void testUpdateMobilePolicyCycleWithNullConfig() throws RemoteException {
1362 when(mConnManager.getAllNetworkState()).thenReturn(new NetworkState[0]);
1363 when(mSubscriptionManager.getActiveSubscriptionIdList()).thenReturn(new int[]{FAKE_SUB_ID});
1364 when(mTelephonyManager.getSubscriberId(FAKE_SUB_ID)).thenReturn(FAKE_SUBSCRIBER_ID);
1365 when(mCarrierConfigManager.getConfigForSubId(FAKE_SUB_ID)).thenReturn(null);
1366 setNetworkPolicies(buildDefaultFakeMobilePolicy());
1367 // smoke test to make sure no errors are raised
1368 mServiceContext.sendBroadcast(
1369 new Intent(ACTION_CARRIER_CONFIG_CHANGED)
1370 .putExtra(PhoneConstants.SUBSCRIPTION_KEY, FAKE_SUB_ID)
1371 );
1372 assertNetworkPolicyEquals(DEFAULT_CYCLE_DAY, mDefaultWarningBytes, mDefaultLimitBytes,
1373 true);
1374 }
1375
1376 @Test
1377 public void testUpdateMobilePolicyCycleWithInvalidConfig() throws RemoteException {
1378 PersistableBundle bundle = setupUpdateMobilePolicyCycleTests();
1379 // Test with an invalid CarrierConfig, there should be no changes or crashes.
1380 bundle.putInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT, -100);
1381 bundle.putLong(CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG, -100);
1382 bundle.putLong(CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG, -100);
1383 mServiceContext.sendBroadcast(
1384 new Intent(ACTION_CARRIER_CONFIG_CHANGED)
1385 .putExtra(PhoneConstants.SUBSCRIPTION_KEY, FAKE_SUB_ID)
1386 );
1387
1388 assertNetworkPolicyEquals(DEFAULT_CYCLE_DAY, mDefaultWarningBytes, mDefaultLimitBytes,
1389 true);
1390 }
1391
1392 @Test
1393 public void testUpdateMobilePolicyCycleWithDefaultConfig() throws RemoteException {
1394 PersistableBundle bundle = setupUpdateMobilePolicyCycleTests();
1395 // Test that we respect the platform values when told to
1396 bundle.putInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT,
1397 DATA_CYCLE_USE_PLATFORM_DEFAULT);
1398 bundle.putLong(CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG,
1399 DATA_CYCLE_USE_PLATFORM_DEFAULT);
1400 bundle.putLong(CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG,
1401 DATA_CYCLE_USE_PLATFORM_DEFAULT);
1402 mServiceContext.sendBroadcast(
1403 new Intent(ACTION_CARRIER_CONFIG_CHANGED)
1404 .putExtra(PhoneConstants.SUBSCRIPTION_KEY, FAKE_SUB_ID)
1405 );
1406
1407 assertNetworkPolicyEquals(DEFAULT_CYCLE_DAY, mDefaultWarningBytes, mDefaultLimitBytes,
1408 true);
1409 }
1410
1411 @Test
1412 public void testUpdateMobilePolicyCycleWithUserOverrides() throws RemoteException {
1413 PersistableBundle bundle = setupUpdateMobilePolicyCycleTests();
1414
1415 // inferred = false implies that a user manually modified this policy.
1416 NetworkPolicy policy = buildDefaultFakeMobilePolicy();
1417 policy.inferred = false;
1418 setNetworkPolicies(policy);
1419
1420 bundle.putInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT, 31);
1421 bundle.putLong(CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG, 9999);
1422 bundle.putLong(CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG,
1423 DATA_CYCLE_THRESHOLD_DISABLED);
1424 mServiceContext.sendBroadcast(
1425 new Intent(ACTION_CARRIER_CONFIG_CHANGED)
1426 .putExtra(PhoneConstants.SUBSCRIPTION_KEY, FAKE_SUB_ID)
1427 );
1428
1429 // The policy still shouldn't change, because we don't want to overwrite user settings.
1430 assertNetworkPolicyEquals(DEFAULT_CYCLE_DAY, mDefaultWarningBytes, mDefaultLimitBytes,
1431 false);
1432 }
1433
1434 @Test
1435 public void testUpdateMobilePolicyCycleUpdatesDataCycle() throws RemoteException {
1436 PersistableBundle bundle = setupUpdateMobilePolicyCycleTests();
1437
1438 bundle.putInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT, 31);
1439 bundle.putLong(CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG, 9999);
1440 bundle.putLong(CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG, 9999);
1441 mServiceContext.sendBroadcast(
1442 new Intent(ACTION_CARRIER_CONFIG_CHANGED)
1443 .putExtra(PhoneConstants.SUBSCRIPTION_KEY, FAKE_SUB_ID)
1444 );
1445
1446 assertNetworkPolicyEquals(31, 9999, 9999, true);
1447 }
1448
1449 @Test
1450 public void testUpdateMobilePolicyCycleDisableThresholds() throws RemoteException {
1451 PersistableBundle bundle = setupUpdateMobilePolicyCycleTests();
1452
1453 bundle.putInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT, 31);
1454 bundle.putLong(CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG,
1455 DATA_CYCLE_THRESHOLD_DISABLED);
1456 bundle.putLong(CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG,
1457 DATA_CYCLE_THRESHOLD_DISABLED);
1458 mServiceContext.sendBroadcast(
1459 new Intent(ACTION_CARRIER_CONFIG_CHANGED)
1460 .putExtra(PhoneConstants.SUBSCRIPTION_KEY, FAKE_SUB_ID)
1461 );
1462
1463 assertNetworkPolicyEquals(31, WARNING_DISABLED, LIMIT_DISABLED, true);
1464 }
1465
1466 @Test
1467 public void testUpdateMobilePolicyCycleRevertsToDefault() throws RemoteException {
1468 PersistableBundle bundle = setupUpdateMobilePolicyCycleTests();
1469
1470 bundle.putInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT, 31);
1471 bundle.putLong(CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG,
1472 DATA_CYCLE_THRESHOLD_DISABLED);
1473 bundle.putLong(CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG,
1474 DATA_CYCLE_THRESHOLD_DISABLED);
1475 mServiceContext.sendBroadcast(
1476 new Intent(ACTION_CARRIER_CONFIG_CHANGED)
1477 .putExtra(PhoneConstants.SUBSCRIPTION_KEY, FAKE_SUB_ID)
1478 );
1479 assertNetworkPolicyEquals(31, WARNING_DISABLED, LIMIT_DISABLED, true);
1480
1481 // If the user switches carriers to one that doesn't use a CarrierConfig, we should revert
1482 // to the default data limit and warning. The cycle date doesn't need to revert as it's
1483 // arbitrary anyways.
1484 bundle.putInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT,
1485 DATA_CYCLE_USE_PLATFORM_DEFAULT);
1486 bundle.putLong(CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG,
1487 DATA_CYCLE_USE_PLATFORM_DEFAULT);
1488 bundle.putLong(CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG,
1489 DATA_CYCLE_USE_PLATFORM_DEFAULT);
1490 mServiceContext.sendBroadcast(
1491 new Intent(ACTION_CARRIER_CONFIG_CHANGED)
1492 .putExtra(PhoneConstants.SUBSCRIPTION_KEY, FAKE_SUB_ID)
1493 );
1494
1495 assertNetworkPolicyEquals(31, mDefaultWarningBytes, mDefaultLimitBytes,
1496 true);
1497 }
1498
Jeff Sharkey36b414b2018-03-30 11:00:03 -06001499 @Test
1500 public void testOpportunisticQuota() throws Exception {
1501 final Network net = new Network(TEST_NET_ID);
1502 final NetworkPolicyManagerInternal internal = LocalServices
1503 .getService(NetworkPolicyManagerInternal.class);
1504
1505 // Create a place to store fake usage
1506 final NetworkStatsHistory history = new NetworkStatsHistory(TimeUnit.HOURS.toMillis(1));
1507 final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 0);
1508 when(mStatsService.getNetworkTotalBytes(any(), anyLong(), anyLong()))
Remi NGUYEN VANed6d2ca2018-04-04 11:12:51 +09001509 .thenAnswer(invocation -> {
1510 final NetworkStatsHistory.Entry entry = history.getValues(
1511 invocation.getArgument(1), invocation.getArgument(2), null);
1512 return entry.rxBytes + entry.txBytes;
Jeff Sharkey36b414b2018-03-30 11:00:03 -06001513 });
1514 when(mStatsService.getNetworkUidBytes(any(), anyLong(), anyLong()))
Remi NGUYEN VANed6d2ca2018-04-04 11:12:51 +09001515 .thenReturn(stats);
Jeff Sharkey36b414b2018-03-30 11:00:03 -06001516
1517 // Get active mobile network in place
1518 expectMobileDefaults();
1519 mService.updateNetworks();
1520
1521 // We're 20% through the month (6 days)
1522 final long start = parseTime("2015-11-01T00:00Z");
1523 final long end = parseTime("2015-11-07T00:00Z");
1524 setCurrentTimeMillis(end);
1525
1526 // Get some data usage in place
1527 history.clear();
1528 history.recordData(start, end,
1529 new NetworkStats.Entry(DataUnit.MEGABYTES.toBytes(360), 0L, 0L, 0L, 0));
1530
1531 // No data plan
1532 {
1533 reset(mTelephonyManager, mNetworkManager, mNotifManager);
1534 expectMobileDefaults();
1535
1536 mService.updateNetworks();
1537
1538 // No quotas
Remi NGUYEN VANed6d2ca2018-04-04 11:12:51 +09001539 assertEquals(OPPORTUNISTIC_QUOTA_UNKNOWN,
1540 internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_JOBS));
1541 assertEquals(OPPORTUNISTIC_QUOTA_UNKNOWN,
1542 internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_MULTIPATH));
Jeff Sharkey36b414b2018-03-30 11:00:03 -06001543 }
1544
1545 // Limited data plan
1546 {
Remi NGUYEN VANed6d2ca2018-04-04 11:12:51 +09001547 final SubscriptionPlan plan = buildMonthlyDataPlan(
1548 ZonedDateTime.parse("2015-11-01T00:00:00.00Z"),
1549 DataUnit.MEGABYTES.toBytes(1800));
1550 mService.setSubscriptionPlans(TEST_SUB_ID, new SubscriptionPlan[]{plan},
Jeff Sharkey36b414b2018-03-30 11:00:03 -06001551 mServiceContext.getOpPackageName());
1552
1553 reset(mTelephonyManager, mNetworkManager, mNotifManager);
1554 expectMobileDefaults();
1555
1556 mService.updateNetworks();
1557
1558 // We have 1440MB and 24 days left, which is 60MB/day; assuming 10%
1559 // for quota split equally between two types gives 3MB.
1560 assertEquals(DataUnit.MEGABYTES.toBytes(3),
1561 internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_JOBS));
1562 assertEquals(DataUnit.MEGABYTES.toBytes(3),
1563 internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_MULTIPATH));
1564 }
1565
Remi NGUYEN VANed6d2ca2018-04-04 11:12:51 +09001566 // Limited data plan, over quota
1567 {
1568 final SubscriptionPlan plan = buildMonthlyDataPlan(
1569 ZonedDateTime.parse("2015-11-01T00:00:00.00Z"),
1570 DataUnit.MEGABYTES.toBytes(100));
1571 mService.setSubscriptionPlans(TEST_SUB_ID, new SubscriptionPlan[]{plan},
1572 mServiceContext.getOpPackageName());
1573
1574 reset(mTelephonyManager, mNetworkManager, mNotifManager);
1575 expectMobileDefaults();
1576
1577 mService.updateNetworks();
1578
1579 assertEquals(0L, internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_JOBS));
1580 assertEquals(0L, internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_MULTIPATH));
1581 }
1582
1583 // Roaming
1584 {
1585 final SubscriptionPlan plan = buildMonthlyDataPlan(
1586 ZonedDateTime.parse("2015-11-01T00:00:00.00Z"), BYTES_UNLIMITED);
1587 mService.setSubscriptionPlans(TEST_SUB_ID, new SubscriptionPlan[]{plan},
1588 mServiceContext.getOpPackageName());
1589
1590 reset(mTelephonyManager, mNetworkManager, mNotifManager);
1591 expectMobileDefaults();
1592 expectNetworkState(true /* roaming */);
1593
1594 mService.updateNetworks();
1595
1596 assertEquals(0L, internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_JOBS));
1597 assertEquals(0L, internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_MULTIPATH));
1598 }
1599
Jeff Sharkey36b414b2018-03-30 11:00:03 -06001600 // Unlimited data plan
1601 {
Remi NGUYEN VANed6d2ca2018-04-04 11:12:51 +09001602 final SubscriptionPlan plan = buildMonthlyDataPlan(
1603 ZonedDateTime.parse("2015-11-01T00:00:00.00Z"), BYTES_UNLIMITED);
1604 mService.setSubscriptionPlans(TEST_SUB_ID, new SubscriptionPlan[]{plan},
Jeff Sharkey36b414b2018-03-30 11:00:03 -06001605 mServiceContext.getOpPackageName());
1606
1607 reset(mTelephonyManager, mNetworkManager, mNotifManager);
1608 expectMobileDefaults();
1609
1610 mService.updateNetworks();
1611
1612 // 20MB/day, split equally between two types gives 10MB.
1613 assertEquals(DataUnit.MEBIBYTES.toBytes(10),
1614 internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_JOBS));
1615 assertEquals(DataUnit.MEBIBYTES.toBytes(10),
1616 internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_MULTIPATH));
Remi NGUYEN VANed6d2ca2018-04-04 11:12:51 +09001617
1618 // Capabilities change to roaming
1619 final ConnectivityManager.NetworkCallback callback = mNetworkCallbackCaptor.getValue();
1620 assertNotNull(callback);
1621 expectNetworkState(true /* roaming */);
1622 callback.onCapabilitiesChanged(
1623 new Network(TEST_NET_ID),
1624 buildNetworkCapabilities(TEST_SUB_ID, true /* roaming */));
1625
1626 assertEquals(0, internal.getSubscriptionOpportunisticQuota(
1627 new Network(TEST_NET_ID), NetworkPolicyManagerInternal.QUOTA_TYPE_MULTIPATH));
Jeff Sharkey36b414b2018-03-30 11:00:03 -06001628 }
1629 }
1630
Remi NGUYEN VANed6d2ca2018-04-04 11:12:51 +09001631 private SubscriptionPlan buildMonthlyDataPlan(ZonedDateTime start, long limitBytes) {
1632 return SubscriptionPlan.Builder
1633 .createRecurringMonthly(start)
1634 .setDataLimit(limitBytes, LIMIT_BEHAVIOR_DISABLED)
1635 .build();
1636 }
1637
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001638 private ApplicationInfo buildApplicationInfo(String label) {
1639 final ApplicationInfo ai = new ApplicationInfo();
1640 ai.nonLocalizedLabel = label;
1641 return ai;
1642 }
1643
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001644 private NetworkInfo buildNetworkInfo() {
1645 final NetworkInfo ni = new NetworkInfo(ConnectivityManager.TYPE_MOBILE,
1646 TelephonyManager.NETWORK_TYPE_LTE, null, null);
1647 ni.setDetailedState(NetworkInfo.DetailedState.CONNECTED, null, null);
1648 return ni;
1649 }
1650
1651 private LinkProperties buildLinkProperties(String iface) {
1652 final LinkProperties lp = new LinkProperties();
1653 lp.setInterfaceName(iface);
1654 return lp;
1655 }
1656
Remi NGUYEN VANed6d2ca2018-04-04 11:12:51 +09001657 private NetworkCapabilities buildNetworkCapabilities(int subId, boolean roaming) {
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001658 final NetworkCapabilities nc = new NetworkCapabilities();
1659 nc.addTransportType(TRANSPORT_CELLULAR);
Remi NGUYEN VANed6d2ca2018-04-04 11:12:51 +09001660 if (!roaming) {
1661 nc.addCapability(NET_CAPABILITY_NOT_ROAMING);
1662 }
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001663 nc.setNetworkSpecifier(new StringNetworkSpecifier(String.valueOf(subId)));
1664 return nc;
1665 }
1666
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07001667 private NetworkPolicy buildDefaultFakeMobilePolicy() {
1668 NetworkPolicy p = mService.buildDefaultMobilePolicy(FAKE_SUB_ID, FAKE_SUBSCRIBER_ID);
1669 // set a deterministic cycle date
Jeff Sharkey17bebd22017-07-19 21:00:38 -06001670 p.cycleRule = new RecurrenceRule(
1671 p.cycleRule.start.withDayOfMonth(DEFAULT_CYCLE_DAY),
1672 p.cycleRule.end, Period.ofMonths(1));
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07001673 return p;
1674 }
1675
1676 private static NetworkPolicy buildFakeMobilePolicy(int cycleDay, long warningBytes,
1677 long limitBytes, boolean inferred){
1678 final NetworkTemplate template = buildTemplateMobileAll(FAKE_SUBSCRIBER_ID);
Sudheer Shankaed25ce62017-03-29 20:46:30 -07001679 return new NetworkPolicy(template, cycleDay, new Time().timezone, warningBytes,
Ammar Aijazi6ce48e22017-03-28 15:43:22 -07001680 limitBytes, SNOOZE_NEVER, SNOOZE_NEVER, true, inferred);
1681 }
1682
1683 private void assertNetworkPolicyEquals(int expectedCycleDay, long expectedWarningBytes,
1684 long expectedLimitBytes, boolean expectedInferred) {
1685 NetworkPolicy[] policies = mService.getNetworkPolicies(
1686 mServiceContext.getOpPackageName());
1687 assertEquals("Unexpected number of network policies", 1, policies.length);
1688 NetworkPolicy actualPolicy = policies[0];
1689 NetworkPolicy expectedPolicy = buildFakeMobilePolicy(expectedCycleDay, expectedWarningBytes,
1690 expectedLimitBytes, expectedInferred);
1691 assertEquals(expectedPolicy, actualPolicy);
1692 }
1693
Jeff Sharkey21c9c452011-06-07 12:26:43 -07001694 private static long parseTime(String time) {
Jeff Sharkey53313d72017-07-13 16:47:32 -06001695 return ZonedDateTime.parse(time).toInstant().toEpochMilli();
Jeff Sharkey21c9c452011-06-07 12:26:43 -07001696 }
1697
Jeff Sharkeyaf11d482011-06-13 00:14:31 -07001698 private void setNetworkPolicies(NetworkPolicy... policies) {
1699 mService.setNetworkPolicies(policies);
1700 }
1701
Jeff Sharkey21c9c452011-06-07 12:26:43 -07001702 private static NetworkState buildWifi() {
1703 final NetworkInfo info = new NetworkInfo(TYPE_WIFI, 0, null, null);
1704 info.setDetailedState(DetailedState.CONNECTED, null, null);
1705 final LinkProperties prop = new LinkProperties();
1706 prop.setInterfaceName(TEST_IFACE);
Stephen Chena1c92b72017-02-06 13:18:11 -08001707 final NetworkCapabilities networkCapabilities = new NetworkCapabilities();
1708 return new NetworkState(info, prop, networkCapabilities, null, null, TEST_SSID);
Jeff Sharkey21c9c452011-06-07 12:26:43 -07001709 }
1710
Felipe Leme3d3308d2016-08-23 17:41:47 -07001711 private void expectHasInternetPermission(int uid, boolean hasIt) throws Exception {
1712 when(mIpm.checkUidPermission(Manifest.permission.INTERNET, uid)).thenReturn(
1713 hasIt ? PackageManager.PERMISSION_GRANTED : PackageManager.PERMISSION_DENIED);
1714 }
1715
Remi NGUYEN VANed6d2ca2018-04-04 11:12:51 +09001716 private void expectNetworkState(boolean roaming) throws Exception {
Jeff Sharkey0a5570d2018-04-10 12:38:29 -06001717 when(mCarrierConfigManager.getConfigForSubId(eq(TEST_SUB_ID)))
1718 .thenReturn(CarrierConfigManager.getDefaultConfig());
Remi NGUYEN VANed6d2ca2018-04-04 11:12:51 +09001719 when(mConnManager.getAllNetworkState()).thenReturn(new NetworkState[] {
1720 new NetworkState(buildNetworkInfo(),
1721 buildLinkProperties(TEST_IFACE),
1722 buildNetworkCapabilities(TEST_SUB_ID, roaming),
1723 new Network(TEST_NET_ID), TEST_IMSI, null)
1724 });
1725 }
1726
Jeff Sharkeybfb43ea2018-02-03 12:08:16 -07001727 private void expectMobileDefaults() throws Exception {
1728 when(mSubscriptionManager.getActiveSubscriptionIdList()).thenReturn(
1729 new int[] { TEST_SUB_ID });
1730 when(mTelephonyManager.getSubscriberId(TEST_SUB_ID)).thenReturn(TEST_IMSI);
Remi NGUYEN VANed6d2ca2018-04-04 11:12:51 +09001731 expectNetworkState(false /* roaming */);
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001732 }
1733
Felipe Lemeef134662016-08-10 14:46:39 -07001734 private void verifyAdvisePersistThreshold() throws Exception {
1735 verify(mStatsService).advisePersistThreshold(anyLong());
Jeff Sharkey0cf6de02012-05-04 15:03:30 -07001736 }
1737
Jeff Sharkey7ee86582011-11-14 18:02:21 -08001738 private static class TestAbstractFuture<T> extends AbstractFuture<T> {
Jeff Sharkey4414cea2011-06-24 17:05:24 -07001739 @Override
Jeff Sharkey7ee86582011-11-14 18:02:21 -08001740 public T get() throws InterruptedException, ExecutionException {
Jeff Sharkey4414cea2011-06-24 17:05:24 -07001741 try {
1742 return get(5, TimeUnit.SECONDS);
1743 } catch (TimeoutException e) {
1744 throw new RuntimeException(e);
1745 }
1746 }
Jeff Sharkey7ee86582011-11-14 18:02:21 -08001747 }
Jeff Sharkey4414cea2011-06-24 17:05:24 -07001748
Jeff Sharkeyaf82ea22011-08-04 15:38:48 -07001749 private static void assertTimeEquals(long expected, long actual) {
1750 if (expected != actual) {
1751 fail("expected " + formatTime(expected) + " but was actually " + formatTime(actual));
1752 }
1753 }
1754
1755 private static String formatTime(long millis) {
Jeff Sharkey53313d72017-07-13 16:47:32 -06001756 return Instant.ofEpochMilli(millis) + " [" + millis + "]";
Jeff Sharkeyaf82ea22011-08-04 15:38:48 -07001757 }
1758
1759 private static void assertEqualsFuzzy(long expected, long actual, long fuzzy) {
1760 final long low = expected - fuzzy;
1761 final long high = expected + fuzzy;
1762 if (actual < low || actual > high) {
Jeff Sharkey53313d72017-07-13 16:47:32 -06001763 fail("value " + formatTime(actual) + " is outside [" + formatTime(low) + ","
1764 + formatTime(high) + "]");
Jeff Sharkeyaf82ea22011-08-04 15:38:48 -07001765 }
1766 }
1767
1768 private static void assertUnique(LinkedHashSet<Long> seen, Long value) {
1769 if (!seen.add(value)) {
1770 fail("found duplicate time " + value + " in series " + seen.toString());
1771 }
1772 }
1773
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001774 private static void assertNotificationType(int expected, String actualTag) {
Felipe Lemeef134662016-08-10 14:46:39 -07001775 assertEquals("notification type mismatch for '" + actualTag +"'",
Jeff Sharkey41ff7ec2011-07-25 15:21:22 -07001776 Integer.toString(expected), actualTag.substring(actualTag.lastIndexOf(':') + 1));
1777 }
1778
Felipe Lemee88729d2016-08-17 16:43:01 -07001779 private void assertUidPolicy(int uid, int expected) {
1780 final int actual = mService.getUidPolicy(uid);
1781 if (expected != actual) {
1782 fail("Wrong policy for UID " + uid + ": expected " + uidPoliciesToString(expected)
1783 + ", actual " + uidPoliciesToString(actual));
1784 }
1785 }
1786
Felipe Leme46b451f2016-08-19 08:46:17 -07001787 private void assertWhitelistUids(int... uids) {
Felipe Leme57e3d312016-08-23 14:42:52 -07001788 assertContainsInAnyOrder(mService.getUidsWithPolicy(POLICY_ALLOW_METERED_BACKGROUND), uids);
Felipe Leme46b451f2016-08-19 08:46:17 -07001789 }
1790
Felipe Leme3d3308d2016-08-23 17:41:47 -07001791 private void assertRestrictBackgroundOn() throws Exception {
1792 assertTrue("restrictBackground should be set", mService.getRestrictBackground());
1793 }
1794
1795 private void assertRestrictBackgroundOff() throws Exception {
1796 assertFalse("restrictBackground should not be set", mService.getRestrictBackground());
1797 }
1798
1799 private FutureIntent newRestrictBackgroundChangedFuture() {
1800 return mServiceContext
1801 .nextBroadcastIntent(ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED);
1802 }
1803
1804 private void assertRestrictBackgroundChangedReceived(Future<Intent> future,
1805 String expectedPackage) throws Exception {
1806 final String action = ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED;
1807 final Intent intent = future.get(5, TimeUnit.SECONDS);
1808 assertNotNull("Didn't get a " + action + "intent in 5 seconds");
1809 assertEquals("Wrong package on " + action + " intent", expectedPackage, intent.getPackage());
1810 }
1811
Felipe Lemee88729d2016-08-17 16:43:01 -07001812 // TODO: replace by Truth, Hamcrest, or a similar tool.
1813 private void assertContainsInAnyOrder(int[] actual, int...expected) {
1814 final StringBuilder errors = new StringBuilder();
1815 if (actual.length != expected.length) {
1816 errors.append("\tsize does not match\n");
1817 }
1818 final List<Integer> actualList =
1819 Arrays.stream(actual).boxed().collect(Collectors.<Integer>toList());
1820 final List<Integer> expectedList =
1821 Arrays.stream(expected).boxed().collect(Collectors.<Integer>toList());
1822 if (!actualList.containsAll(expectedList)) {
1823 errors.append("\tmissing elements on actual list\n");
1824 }
1825 if (!expectedList.containsAll(actualList)) {
1826 errors.append("\tmissing elements on expected list\n");
1827 }
1828 if (errors.length() > 0) {
1829 fail("assertContainsInAnyOrder(expected=" + Arrays.toString(expected)
1830 + ", actual=" + Arrays.toString(actual) +") failed: \n" + errors);
1831 }
1832 }
1833
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001834 private long getElapsedRealtime() {
1835 return mElapsedRealtime;
1836 }
1837
1838 private void setCurrentTimeMillis(long currentTimeMillis) {
Jeff Sharkey17bebd22017-07-19 21:00:38 -06001839 RecurrenceRule.sClock = Clock.fixed(Instant.ofEpochMilli(currentTimeMillis),
1840 ZoneId.systemDefault());
Jeff Sharkey8e28b7d2011-08-19 02:24:24 -07001841 mStartTime = currentTimeMillis;
1842 mElapsedRealtime = 0L;
1843 }
1844
1845 private long currentTimeMillis() {
1846 return mStartTime + mElapsedRealtime;
1847 }
1848
1849 private void incrementCurrentTime(long duration) {
1850 mElapsedRealtime += duration;
1851 }
1852
Felipe Leme3d3308d2016-08-23 17:41:47 -07001853 private FutureIntent mRestrictBackgroundChanged;
1854
1855 private void setRestrictBackground(boolean flag) throws Exception {
Felipe Leme3d3308d2016-08-23 17:41:47 -07001856 mService.setRestrictBackground(flag);
1857 // Sanity check.
1858 assertEquals("restrictBackground not set", flag, mService.getRestrictBackground());
1859 }
1860
Felipe Lemeef134662016-08-10 14:46:39 -07001861 /**
1862 * Creates a mock and registers it to {@link LocalServices}.
1863 */
Felipe Leme9f27e7a2016-08-12 15:19:40 -07001864 private static <T> T addLocalServiceMock(Class<T> clazz) {
Felipe Lemeef134662016-08-10 14:46:39 -07001865 final T mock = mock(clazz);
Felipe Lemeef134662016-08-10 14:46:39 -07001866 LocalServices.addService(clazz, mock);
Felipe Lemeef134662016-08-10 14:46:39 -07001867 return mock;
1868 }
1869
1870 /**
Felipe Lemeef134662016-08-10 14:46:39 -07001871 * Custom Mockito answer used to verify async {@link INetworkPolicyListener} calls.
1872 *
1873 * <p>Typical usage:
1874 * <pre><code>
1875 * mPolicyListener.expect().someCallback(any());
1876 * // do something on objects under test
1877 * mPolicyListener.waitAndVerify().someCallback(eq(expectedValue));
1878 * </code></pre>
1879 */
1880 final class NetworkPolicyListenerAnswer implements Answer<Void> {
1881 private CountDownLatch latch;
1882 private final INetworkPolicyListener listener;
1883
1884 NetworkPolicyListenerAnswer(NetworkPolicyManagerService service) {
1885 this.listener = mock(INetworkPolicyListener.class);
1886 // RemoteCallbackList needs a binder to use as key
1887 when(listener.asBinder()).thenReturn(new Binder());
1888 service.registerListener(listener);
1889 }
1890
1891 @Override
1892 public Void answer(InvocationOnMock invocation) throws Throwable {
1893 Log.d(TAG,"counting down on answer: " + invocation);
1894 latch.countDown();
1895 return null;
1896 }
1897
1898 INetworkPolicyListener expect() {
1899 assertNull("expect() called before waitAndVerify()", latch);
1900 latch = new CountDownLatch(1);
1901 return doAnswer(this).when(listener);
1902 }
1903
1904 INetworkPolicyListener waitAndVerify() {
1905 assertNotNull("waitAndVerify() called before expect()", latch);
1906 try {
1907 assertTrue("callback not called in 5 seconds", latch.await(5, TimeUnit.SECONDS));
1908 } catch (InterruptedException e) {
1909 fail("Thread interrupted before callback called");
1910 } finally {
1911 latch = null;
1912 }
1913 return verify(listener, atLeastOnce());
1914 }
Felipe Leme3d3308d2016-08-23 17:41:47 -07001915
1916 INetworkPolicyListener verifyNotCalled() {
1917 return verify(listener, never());
1918 }
1919
Jeff Sharkey9599cc52011-05-22 14:59:31 -07001920 }
Felipe Lemee88729d2016-08-17 16:43:01 -07001921
1922 private void setNetpolicyXml(Context context) throws Exception {
1923 mPolicyDir = context.getFilesDir();
1924 if (mPolicyDir.exists()) {
1925 IoUtils.deleteContents(mPolicyDir);
1926 }
1927 if (!TextUtils.isEmpty(mNetpolicyXml)) {
1928 final String assetPath = NETPOLICY_DIR + "/" + mNetpolicyXml;
1929 final File netConfigFile = new File(mPolicyDir, "netpolicy.xml");
1930 Log.d(TAG, "Creating " + netConfigFile + " from asset " + assetPath);
1931 try (final InputStream in = context.getResources().getAssets().open(assetPath);
1932 final OutputStream out = new FileOutputStream(netConfigFile)) {
1933 Streams.copy(in, out);
1934 }
1935 }
1936 }
1937
1938 /**
1939 * Annotation used to define the relative path of the {@code netpolicy.xml} file.
1940 */
1941 @Retention(RetentionPolicy.RUNTIME)
1942 @Target(ElementType.METHOD)
1943 public @interface NetPolicyXml {
1944
1945 public String value() default "";
1946
1947 }
1948
1949 /**
1950 * Rule used to set {@code mNetPolicyXml} according to the {@link NetPolicyXml} annotation.
1951 */
1952 public static class NetPolicyMethodRule implements MethodRule {
1953
1954 @Override
1955 public Statement apply(Statement base, FrameworkMethod method, Object target) {
1956 for (Annotation annotation : method.getAnnotations()) {
1957 if ((annotation instanceof NetPolicyXml)) {
1958 final String path = ((NetPolicyXml) annotation).value();
1959 if (!path.isEmpty()) {
1960 ((NetworkPolicyManagerServiceTest) target).mNetpolicyXml = path;
1961 break;
1962 }
1963 }
1964 }
1965 return base;
1966 }
1967 }
Jeff Sharkey9599cc52011-05-22 14:59:31 -07001968}