Home | History | Annotate | Download | only in server
      1 /*
      2  * Copyright (C) 2011 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.server;
     18 
     19 import static android.content.Intent.ACTION_UID_REMOVED;
     20 import static android.content.Intent.EXTRA_UID;
     21 import static android.net.ConnectivityManager.CONNECTIVITY_ACTION_IMMEDIATE;
     22 import static android.net.ConnectivityManager.TYPE_WIFI;
     23 import static android.net.NetworkPolicy.LIMIT_DISABLED;
     24 import static android.net.NetworkPolicy.WARNING_DISABLED;
     25 import static android.net.NetworkPolicyManager.POLICY_NONE;
     26 import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND;
     27 import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL;
     28 import static android.net.NetworkPolicyManager.RULE_REJECT_METERED;
     29 import static android.net.NetworkPolicyManager.computeLastCycleBoundary;
     30 import static android.net.NetworkPolicyManager.computeNextCycleBoundary;
     31 import static android.net.TrafficStats.KB_IN_BYTES;
     32 import static android.net.TrafficStats.MB_IN_BYTES;
     33 import static android.text.format.DateUtils.DAY_IN_MILLIS;
     34 import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
     35 import static android.text.format.Time.TIMEZONE_UTC;
     36 import static com.android.server.net.NetworkPolicyManagerService.TYPE_LIMIT;
     37 import static com.android.server.net.NetworkPolicyManagerService.TYPE_LIMIT_SNOOZED;
     38 import static com.android.server.net.NetworkPolicyManagerService.TYPE_WARNING;
     39 import static org.easymock.EasyMock.anyInt;
     40 import static org.easymock.EasyMock.anyLong;
     41 import static org.easymock.EasyMock.aryEq;
     42 import static org.easymock.EasyMock.capture;
     43 import static org.easymock.EasyMock.createMock;
     44 import static org.easymock.EasyMock.eq;
     45 import static org.easymock.EasyMock.expect;
     46 import static org.easymock.EasyMock.expectLastCall;
     47 import static org.easymock.EasyMock.isA;
     48 
     49 import android.app.IActivityManager;
     50 import android.app.INotificationManager;
     51 import android.app.IProcessObserver;
     52 import android.app.Notification;
     53 import android.content.Intent;
     54 import android.content.pm.PackageInfo;
     55 import android.content.pm.PackageManager;
     56 import android.content.pm.Signature;
     57 import android.net.ConnectivityManager;
     58 import android.net.IConnectivityManager;
     59 import android.net.INetworkManagementEventObserver;
     60 import android.net.INetworkPolicyListener;
     61 import android.net.INetworkStatsService;
     62 import android.net.LinkProperties;
     63 import android.net.NetworkInfo;
     64 import android.net.NetworkInfo.DetailedState;
     65 import android.net.NetworkPolicy;
     66 import android.net.NetworkState;
     67 import android.net.NetworkStats;
     68 import android.net.NetworkTemplate;
     69 import android.os.Binder;
     70 import android.os.INetworkManagementService;
     71 import android.os.IPowerManager;
     72 import android.os.MessageQueue.IdleHandler;
     73 import android.os.UserHandle;
     74 import android.test.AndroidTestCase;
     75 import android.test.mock.MockPackageManager;
     76 import android.test.suitebuilder.annotation.LargeTest;
     77 import android.test.suitebuilder.annotation.Suppress;
     78 import android.text.format.Time;
     79 import android.util.TrustedTime;
     80 
     81 import com.android.server.net.NetworkPolicyManagerService;
     82 import com.google.common.util.concurrent.AbstractFuture;
     83 
     84 import org.easymock.Capture;
     85 import org.easymock.EasyMock;
     86 import org.easymock.IAnswer;
     87 
     88 import java.io.File;
     89 import java.util.LinkedHashSet;
     90 import java.util.concurrent.ExecutionException;
     91 import java.util.concurrent.Future;
     92 import java.util.concurrent.TimeUnit;
     93 import java.util.concurrent.TimeoutException;
     94 import java.util.logging.Handler;
     95 
     96 import libcore.io.IoUtils;
     97 
     98 /**
     99  * Tests for {@link NetworkPolicyManagerService}.
    100  */
    101 @LargeTest
    102 public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
    103     private static final String TAG = "NetworkPolicyManagerServiceTest";
    104 
    105     private static final long TEST_START = 1194220800000L;
    106     private static final String TEST_IFACE = "test0";
    107     private static final String TEST_SSID = "AndroidAP";
    108 
    109     private static NetworkTemplate sTemplateWifi = NetworkTemplate.buildTemplateWifi(TEST_SSID);
    110 
    111     private BroadcastInterceptingContext mServiceContext;
    112     private File mPolicyDir;
    113 
    114     private IActivityManager mActivityManager;
    115     private IPowerManager mPowerManager;
    116     private INetworkStatsService mStatsService;
    117     private INetworkManagementService mNetworkManager;
    118     private INetworkPolicyListener mPolicyListener;
    119     private TrustedTime mTime;
    120     private IConnectivityManager mConnManager;
    121     private INotificationManager mNotifManager;
    122 
    123     private NetworkPolicyManagerService mService;
    124     private IProcessObserver mProcessObserver;
    125     private INetworkManagementEventObserver mNetworkObserver;
    126 
    127     private Binder mStubBinder = new Binder();
    128 
    129     private long mStartTime;
    130     private long mElapsedRealtime;
    131 
    132     private static final int USER_ID = 0;
    133 
    134     private static final int APP_ID_A = android.os.Process.FIRST_APPLICATION_UID + 800;
    135     private static final int APP_ID_B = android.os.Process.FIRST_APPLICATION_UID + 801;
    136 
    137     private static final int UID_A = UserHandle.getUid(USER_ID, APP_ID_A);
    138     private static final int UID_B = UserHandle.getUid(USER_ID, APP_ID_B);
    139 
    140     private static final int PID_1 = 400;
    141     private static final int PID_2 = 401;
    142     private static final int PID_3 = 402;
    143 
    144     @Override
    145     public void setUp() throws Exception {
    146         super.setUp();
    147 
    148         setCurrentTimeMillis(TEST_START);
    149 
    150         // intercept various broadcasts, and pretend that uids have packages
    151         mServiceContext = new BroadcastInterceptingContext(getContext()) {
    152             @Override
    153             public PackageManager getPackageManager() {
    154                 return new MockPackageManager() {
    155                     @Override
    156                     public String[] getPackagesForUid(int uid) {
    157                         return new String[] { "com.example" };
    158                     }
    159 
    160                     @Override
    161                     public PackageInfo getPackageInfo(String packageName, int flags) {
    162                         final PackageInfo info = new PackageInfo();
    163                         final Signature signature;
    164                         if ("android".equals(packageName)) {
    165                             signature = new Signature("F00D");
    166                         } else {
    167                             signature = new Signature("DEAD");
    168                         }
    169                         info.signatures = new Signature[] { signature };
    170                         return info;
    171                     }
    172 
    173                 };
    174             }
    175 
    176             @Override
    177             public void startActivity(Intent intent) {
    178                 // ignored
    179             }
    180         };
    181 
    182         mPolicyDir = getContext().getFilesDir();
    183         if (mPolicyDir.exists()) {
    184             IoUtils.deleteContents(mPolicyDir);
    185         }
    186 
    187         mActivityManager = createMock(IActivityManager.class);
    188         mPowerManager = createMock(IPowerManager.class);
    189         mStatsService = createMock(INetworkStatsService.class);
    190         mNetworkManager = createMock(INetworkManagementService.class);
    191         mPolicyListener = createMock(INetworkPolicyListener.class);
    192         mTime = createMock(TrustedTime.class);
    193         mConnManager = createMock(IConnectivityManager.class);
    194         mNotifManager = createMock(INotificationManager.class);
    195 
    196         mService = new NetworkPolicyManagerService(mServiceContext, mActivityManager, mPowerManager,
    197                 mStatsService, mNetworkManager, mTime, mPolicyDir, true);
    198         mService.bindConnectivityManager(mConnManager);
    199         mService.bindNotificationManager(mNotifManager);
    200 
    201         // RemoteCallbackList needs a binder to use as key
    202         expect(mPolicyListener.asBinder()).andReturn(mStubBinder).atLeastOnce();
    203         replay();
    204         mService.registerListener(mPolicyListener);
    205         verifyAndReset();
    206 
    207         // catch IProcessObserver during systemReady()
    208         final Capture<IProcessObserver> processObserver = new Capture<IProcessObserver>();
    209         mActivityManager.registerProcessObserver(capture(processObserver));
    210         expectLastCall().atLeastOnce();
    211 
    212         // catch INetworkManagementEventObserver during systemReady()
    213         final Capture<INetworkManagementEventObserver> networkObserver = new Capture<
    214                 INetworkManagementEventObserver>();
    215         mNetworkManager.registerObserver(capture(networkObserver));
    216         expectLastCall().atLeastOnce();
    217 
    218         // expect to answer screen status during systemReady()
    219         expect(mPowerManager.isScreenOn()).andReturn(true).atLeastOnce();
    220         expect(mNetworkManager.isBandwidthControlEnabled()).andReturn(true).atLeastOnce();
    221         expectCurrentTime();
    222 
    223         replay();
    224         mService.systemReady();
    225         verifyAndReset();
    226 
    227         mProcessObserver = processObserver.getValue();
    228         mNetworkObserver = networkObserver.getValue();
    229 
    230     }
    231 
    232     @Override
    233     public void tearDown() throws Exception {
    234         for (File file : mPolicyDir.listFiles()) {
    235             file.delete();
    236         }
    237 
    238         mServiceContext = null;
    239         mPolicyDir = null;
    240 
    241         mActivityManager = null;
    242         mPowerManager = null;
    243         mStatsService = null;
    244         mPolicyListener = null;
    245         mTime = null;
    246 
    247         mService = null;
    248         mProcessObserver = null;
    249 
    250         super.tearDown();
    251     }
    252 
    253     @Suppress
    254     public void testPolicyChangeTriggersBroadcast() throws Exception {
    255         mService.setUidPolicy(APP_ID_A, POLICY_NONE);
    256 
    257         // change background policy and expect broadcast
    258         final Future<Intent> backgroundChanged = mServiceContext.nextBroadcastIntent(
    259                 ConnectivityManager.ACTION_BACKGROUND_DATA_SETTING_CHANGED);
    260 
    261         mService.setUidPolicy(APP_ID_A, POLICY_REJECT_METERED_BACKGROUND);
    262 
    263         backgroundChanged.get();
    264     }
    265 
    266     public void testPidForegroundCombined() throws Exception {
    267         IdleFuture idle;
    268 
    269         // push all uid into background
    270         idle = expectIdle();
    271         mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, false);
    272         mProcessObserver.onForegroundActivitiesChanged(PID_2, UID_A, false);
    273         mProcessObserver.onForegroundActivitiesChanged(PID_3, UID_B, false);
    274         idle.get();
    275         assertFalse(mService.isUidForeground(UID_A));
    276         assertFalse(mService.isUidForeground(UID_B));
    277 
    278         // push one of the shared pids into foreground
    279         idle = expectIdle();
    280         mProcessObserver.onForegroundActivitiesChanged(PID_2, UID_A, true);
    281         idle.get();
    282         assertTrue(mService.isUidForeground(UID_A));
    283         assertFalse(mService.isUidForeground(UID_B));
    284 
    285         // and swap another uid into foreground
    286         idle = expectIdle();
    287         mProcessObserver.onForegroundActivitiesChanged(PID_2, UID_A, false);
    288         mProcessObserver.onForegroundActivitiesChanged(PID_3, UID_B, true);
    289         idle.get();
    290         assertFalse(mService.isUidForeground(UID_A));
    291         assertTrue(mService.isUidForeground(UID_B));
    292 
    293         // push both pid into foreground
    294         idle = expectIdle();
    295         mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, true);
    296         mProcessObserver.onForegroundActivitiesChanged(PID_2, UID_A, true);
    297         idle.get();
    298         assertTrue(mService.isUidForeground(UID_A));
    299 
    300         // pull one out, should still be foreground
    301         idle = expectIdle();
    302         mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, false);
    303         idle.get();
    304         assertTrue(mService.isUidForeground(UID_A));
    305 
    306         // pull final pid out, should now be background
    307         idle = expectIdle();
    308         mProcessObserver.onForegroundActivitiesChanged(PID_2, UID_A, false);
    309         idle.get();
    310         assertFalse(mService.isUidForeground(UID_A));
    311     }
    312 
    313     public void testScreenChangesRules() throws Exception {
    314         Future<Void> future;
    315 
    316         expectSetUidNetworkRules(UID_A, false);
    317         expectSetUidForeground(UID_A, true);
    318         future = expectRulesChanged(UID_A, RULE_ALLOW_ALL);
    319         replay();
    320         mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, true);
    321         future.get();
    322         verifyAndReset();
    323 
    324         // push strict policy for foreground uid, verify ALLOW rule
    325         expectSetUidNetworkRules(UID_A, false);
    326         expectSetUidForeground(UID_A, true);
    327         future = expectRulesChanged(UID_A, RULE_ALLOW_ALL);
    328         replay();
    329         mService.setUidPolicy(APP_ID_A, POLICY_REJECT_METERED_BACKGROUND);
    330         future.get();
    331         verifyAndReset();
    332 
    333         // now turn screen off and verify REJECT rule
    334         expect(mPowerManager.isScreenOn()).andReturn(false).atLeastOnce();
    335         expectSetUidNetworkRules(UID_A, true);
    336         expectSetUidForeground(UID_A, false);
    337         future = expectRulesChanged(UID_A, RULE_REJECT_METERED);
    338         replay();
    339         mServiceContext.sendBroadcast(new Intent(Intent.ACTION_SCREEN_OFF));
    340         future.get();
    341         verifyAndReset();
    342 
    343         // and turn screen back on, verify ALLOW rule restored
    344         expect(mPowerManager.isScreenOn()).andReturn(true).atLeastOnce();
    345         expectSetUidNetworkRules(UID_A, false);
    346         expectSetUidForeground(UID_A, true);
    347         future = expectRulesChanged(UID_A, RULE_ALLOW_ALL);
    348         replay();
    349         mServiceContext.sendBroadcast(new Intent(Intent.ACTION_SCREEN_ON));
    350         future.get();
    351         verifyAndReset();
    352     }
    353 
    354     public void testPolicyNone() throws Exception {
    355         Future<Void> future;
    356 
    357         expectSetUidNetworkRules(UID_A, false);
    358         expectSetUidForeground(UID_A, true);
    359         future = expectRulesChanged(UID_A, RULE_ALLOW_ALL);
    360         replay();
    361         mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, true);
    362         future.get();
    363         verifyAndReset();
    364 
    365         // POLICY_NONE should RULE_ALLOW in foreground
    366         expectSetUidNetworkRules(UID_A, false);
    367         expectSetUidForeground(UID_A, true);
    368         future = expectRulesChanged(UID_A, RULE_ALLOW_ALL);
    369         replay();
    370         mService.setUidPolicy(APP_ID_A, POLICY_NONE);
    371         future.get();
    372         verifyAndReset();
    373 
    374         // POLICY_NONE should RULE_ALLOW in background
    375         expectSetUidNetworkRules(UID_A, false);
    376         expectSetUidForeground(UID_A, false);
    377         future = expectRulesChanged(UID_A, RULE_ALLOW_ALL);
    378         replay();
    379         mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, false);
    380         future.get();
    381         verifyAndReset();
    382     }
    383 
    384     public void testPolicyReject() throws Exception {
    385         Future<Void> future;
    386 
    387         // POLICY_REJECT should RULE_ALLOW in background
    388         expectSetUidNetworkRules(UID_A, true);
    389         expectSetUidForeground(UID_A, false);
    390         future = expectRulesChanged(UID_A, RULE_REJECT_METERED);
    391         replay();
    392         mService.setUidPolicy(APP_ID_A, POLICY_REJECT_METERED_BACKGROUND);
    393         future.get();
    394         verifyAndReset();
    395 
    396         // POLICY_REJECT should RULE_ALLOW in foreground
    397         expectSetUidNetworkRules(UID_A, false);
    398         expectSetUidForeground(UID_A, true);
    399         future = expectRulesChanged(UID_A, RULE_ALLOW_ALL);
    400         replay();
    401         mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, true);
    402         future.get();
    403         verifyAndReset();
    404 
    405         // POLICY_REJECT should RULE_REJECT in background
    406         expectSetUidNetworkRules(UID_A, true);
    407         expectSetUidForeground(UID_A, false);
    408         future = expectRulesChanged(UID_A, RULE_REJECT_METERED);
    409         replay();
    410         mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, false);
    411         future.get();
    412         verifyAndReset();
    413     }
    414 
    415     public void testPolicyRejectAddRemove() throws Exception {
    416         Future<Void> future;
    417 
    418         // POLICY_NONE should have RULE_ALLOW in background
    419         expectSetUidNetworkRules(UID_A, false);
    420         expectSetUidForeground(UID_A, false);
    421         future = expectRulesChanged(UID_A, RULE_ALLOW_ALL);
    422         replay();
    423         mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, false);
    424         mService.setUidPolicy(APP_ID_A, POLICY_NONE);
    425         future.get();
    426         verifyAndReset();
    427 
    428         // adding POLICY_REJECT should cause RULE_REJECT
    429         expectSetUidNetworkRules(UID_A, true);
    430         expectSetUidForeground(UID_A, false);
    431         future = expectRulesChanged(UID_A, RULE_REJECT_METERED);
    432         replay();
    433         mService.setUidPolicy(APP_ID_A, POLICY_REJECT_METERED_BACKGROUND);
    434         future.get();
    435         verifyAndReset();
    436 
    437         // removing POLICY_REJECT should return us to RULE_ALLOW
    438         expectSetUidNetworkRules(UID_A, false);
    439         expectSetUidForeground(UID_A, false);
    440         future = expectRulesChanged(UID_A, RULE_ALLOW_ALL);
    441         replay();
    442         mService.setUidPolicy(APP_ID_A, POLICY_NONE);
    443         future.get();
    444         verifyAndReset();
    445     }
    446 
    447     public void testLastCycleBoundaryThisMonth() throws Exception {
    448         // assume cycle day of "5th", which should be in same month
    449         final long currentTime = parseTime("2007-11-14T00:00:00.000Z");
    450         final long expectedCycle = parseTime("2007-11-05T00:00:00.000Z");
    451 
    452         final NetworkPolicy policy = new NetworkPolicy(
    453                 sTemplateWifi, 5, TIMEZONE_UTC, 1024L, 1024L, false);
    454         final long actualCycle = computeLastCycleBoundary(currentTime, policy);
    455         assertTimeEquals(expectedCycle, actualCycle);
    456     }
    457 
    458     public void testLastCycleBoundaryLastMonth() throws Exception {
    459         // assume cycle day of "20th", which should be in last month
    460         final long currentTime = parseTime("2007-11-14T00:00:00.000Z");
    461         final long expectedCycle = parseTime("2007-10-20T00:00:00.000Z");
    462 
    463         final NetworkPolicy policy = new NetworkPolicy(
    464                 sTemplateWifi, 20, TIMEZONE_UTC, 1024L, 1024L, false);
    465         final long actualCycle = computeLastCycleBoundary(currentTime, policy);
    466         assertTimeEquals(expectedCycle, actualCycle);
    467     }
    468 
    469     public void testLastCycleBoundaryThisMonthFebruary() throws Exception {
    470         // assume cycle day of "30th" in february; should go to january
    471         final long currentTime = parseTime("2007-02-14T00:00:00.000Z");
    472         final long expectedCycle = parseTime("2007-01-30T00:00:00.000Z");
    473 
    474         final NetworkPolicy policy = new NetworkPolicy(
    475                 sTemplateWifi, 30, TIMEZONE_UTC, 1024L, 1024L, false);
    476         final long actualCycle = computeLastCycleBoundary(currentTime, policy);
    477         assertTimeEquals(expectedCycle, actualCycle);
    478     }
    479 
    480     public void testLastCycleBoundaryLastMonthFebruary() throws Exception {
    481         // assume cycle day of "30th" in february, which should clamp
    482         final long currentTime = parseTime("2007-03-14T00:00:00.000Z");
    483         final long expectedCycle = parseTime("2007-02-28T23:59:59.000Z");
    484 
    485         final NetworkPolicy policy = new NetworkPolicy(
    486                 sTemplateWifi, 30, TIMEZONE_UTC, 1024L, 1024L, false);
    487         final long actualCycle = computeLastCycleBoundary(currentTime, policy);
    488         assertTimeEquals(expectedCycle, actualCycle);
    489     }
    490 
    491     public void testCycleBoundaryLeapYear() throws Exception {
    492         final NetworkPolicy policy = new NetworkPolicy(
    493                 sTemplateWifi, 29, TIMEZONE_UTC, 1024L, 1024L, false);
    494 
    495         assertTimeEquals(parseTime("2012-01-29T00:00:00.000Z"),
    496                 computeNextCycleBoundary(parseTime("2012-01-14T00:00:00.000Z"), policy));
    497         assertTimeEquals(parseTime("2012-02-29T00:00:00.000Z"),
    498                 computeNextCycleBoundary(parseTime("2012-02-14T00:00:00.000Z"), policy));
    499         assertTimeEquals(parseTime("2012-02-29T00:00:00.000Z"),
    500                 computeLastCycleBoundary(parseTime("2012-03-14T00:00:00.000Z"), policy));
    501         assertTimeEquals(parseTime("2012-03-29T00:00:00.000Z"),
    502                 computeNextCycleBoundary(parseTime("2012-03-14T00:00:00.000Z"), policy));
    503 
    504         assertTimeEquals(parseTime("2007-01-29T00:00:00.000Z"),
    505                 computeNextCycleBoundary(parseTime("2007-01-14T00:00:00.000Z"), policy));
    506         assertTimeEquals(parseTime("2007-02-28T23:59:59.000Z"),
    507                 computeNextCycleBoundary(parseTime("2007-02-14T00:00:00.000Z"), policy));
    508         assertTimeEquals(parseTime("2007-02-28T23:59:59.000Z"),
    509                 computeLastCycleBoundary(parseTime("2007-03-14T00:00:00.000Z"), policy));
    510         assertTimeEquals(parseTime("2007-03-29T00:00:00.000Z"),
    511                 computeNextCycleBoundary(parseTime("2007-03-14T00:00:00.000Z"), policy));
    512     }
    513 
    514     public void testNextCycleTimezoneAfterUtc() throws Exception {
    515         // US/Central is UTC-6
    516         final NetworkPolicy policy = new NetworkPolicy(
    517                 sTemplateWifi, 10, "US/Central", 1024L, 1024L, false);
    518         assertTimeEquals(parseTime("2012-01-10T06:00:00.000Z"),
    519                 computeNextCycleBoundary(parseTime("2012-01-05T00:00:00.000Z"), policy));
    520     }
    521 
    522     public void testNextCycleTimezoneBeforeUtc() throws Exception {
    523         // Israel is UTC+2
    524         final NetworkPolicy policy = new NetworkPolicy(
    525                 sTemplateWifi, 10, "Israel", 1024L, 1024L, false);
    526         assertTimeEquals(parseTime("2012-01-09T22:00:00.000Z"),
    527                 computeNextCycleBoundary(parseTime("2012-01-05T00:00:00.000Z"), policy));
    528     }
    529 
    530     public void testNextCycleSane() throws Exception {
    531         final NetworkPolicy policy = new NetworkPolicy(
    532                 sTemplateWifi, 31, TIMEZONE_UTC, WARNING_DISABLED, LIMIT_DISABLED, false);
    533         final LinkedHashSet<Long> seen = new LinkedHashSet<Long>();
    534 
    535         // walk forwards, ensuring that cycle boundaries don't get stuck
    536         long currentCycle = computeNextCycleBoundary(parseTime("2011-08-01T00:00:00.000Z"), policy);
    537         for (int i = 0; i < 128; i++) {
    538             long nextCycle = computeNextCycleBoundary(currentCycle, policy);
    539             assertEqualsFuzzy(DAY_IN_MILLIS * 30, nextCycle - currentCycle, DAY_IN_MILLIS * 3);
    540             assertUnique(seen, nextCycle);
    541             currentCycle = nextCycle;
    542         }
    543     }
    544 
    545     public void testLastCycleSane() throws Exception {
    546         final NetworkPolicy policy = new NetworkPolicy(
    547                 sTemplateWifi, 31, TIMEZONE_UTC, WARNING_DISABLED, LIMIT_DISABLED, false);
    548         final LinkedHashSet<Long> seen = new LinkedHashSet<Long>();
    549 
    550         // walk backwards, ensuring that cycle boundaries look sane
    551         long currentCycle = computeLastCycleBoundary(parseTime("2011-08-04T00:00:00.000Z"), policy);
    552         for (int i = 0; i < 128; i++) {
    553             long lastCycle = computeLastCycleBoundary(currentCycle, policy);
    554             assertEqualsFuzzy(DAY_IN_MILLIS * 30, currentCycle - lastCycle, DAY_IN_MILLIS * 3);
    555             assertUnique(seen, lastCycle);
    556             currentCycle = lastCycle;
    557         }
    558     }
    559 
    560     public void testNetworkPolicyAppliedCycleLastMonth() throws Exception {
    561         NetworkState[] state = null;
    562         NetworkStats stats = null;
    563         Future<Void> future;
    564 
    565         final long TIME_FEB_15 = 1171497600000L;
    566         final long TIME_MAR_10 = 1173484800000L;
    567         final int CYCLE_DAY = 15;
    568 
    569         setCurrentTimeMillis(TIME_MAR_10);
    570 
    571         // first, pretend that wifi network comes online. no policy active,
    572         // which means we shouldn't push limit to interface.
    573         state = new NetworkState[] { buildWifi() };
    574         expect(mConnManager.getAllNetworkState()).andReturn(state).atLeastOnce();
    575         expectCurrentTime();
    576         expectClearNotifications();
    577         expectAdvisePersistThreshold();
    578         future = expectMeteredIfacesChanged();
    579 
    580         replay();
    581         mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
    582         future.get();
    583         verifyAndReset();
    584 
    585         // now change cycle to be on 15th, and test in early march, to verify we
    586         // pick cycle day in previous month.
    587         expect(mConnManager.getAllNetworkState()).andReturn(state).atLeastOnce();
    588         expectCurrentTime();
    589 
    590         // pretend that 512 bytes total have happened
    591         stats = new NetworkStats(getElapsedRealtime(), 1)
    592                 .addIfaceValues(TEST_IFACE, 256L, 2L, 256L, 2L);
    593         expect(mStatsService.getNetworkTotalBytes(sTemplateWifi, TIME_FEB_15, TIME_MAR_10))
    594                 .andReturn(stats.getTotalBytes()).atLeastOnce();
    595         expectPolicyDataEnable(TYPE_WIFI, true);
    596 
    597         // TODO: consider making strongly ordered mock
    598         expectRemoveInterfaceQuota(TEST_IFACE);
    599         expectSetInterfaceQuota(TEST_IFACE, (2 * MB_IN_BYTES) - 512);
    600 
    601         expectClearNotifications();
    602         expectAdvisePersistThreshold();
    603         future = expectMeteredIfacesChanged(TEST_IFACE);
    604 
    605         replay();
    606         setNetworkPolicies(new NetworkPolicy(
    607                 sTemplateWifi, CYCLE_DAY, TIMEZONE_UTC, 1 * MB_IN_BYTES, 2 * MB_IN_BYTES, false));
    608         future.get();
    609         verifyAndReset();
    610     }
    611 
    612     public void testUidRemovedPolicyCleared() throws Exception {
    613         Future<Void> future;
    614 
    615         // POLICY_REJECT should RULE_REJECT in background
    616         expectSetUidNetworkRules(UID_A, true);
    617         expectSetUidForeground(UID_A, false);
    618         future = expectRulesChanged(UID_A, RULE_REJECT_METERED);
    619         replay();
    620         mService.setUidPolicy(APP_ID_A, POLICY_REJECT_METERED_BACKGROUND);
    621         future.get();
    622         verifyAndReset();
    623 
    624         // uninstall should clear RULE_REJECT
    625         expectSetUidNetworkRules(UID_A, false);
    626         expectSetUidForeground(UID_A, false);
    627         future = expectRulesChanged(UID_A, RULE_ALLOW_ALL);
    628         replay();
    629         final Intent intent = new Intent(ACTION_UID_REMOVED);
    630         intent.putExtra(EXTRA_UID, UID_A);
    631         mServiceContext.sendBroadcast(intent);
    632         future.get();
    633         verifyAndReset();
    634     }
    635 
    636     public void testOverWarningLimitNotification() throws Exception {
    637         NetworkState[] state = null;
    638         NetworkStats stats = null;
    639         Future<Void> future;
    640         Future<String> tagFuture;
    641 
    642         final long TIME_FEB_15 = 1171497600000L;
    643         final long TIME_MAR_10 = 1173484800000L;
    644         final int CYCLE_DAY = 15;
    645 
    646         setCurrentTimeMillis(TIME_MAR_10);
    647 
    648         // assign wifi policy
    649         state = new NetworkState[] {};
    650         stats = new NetworkStats(getElapsedRealtime(), 1)
    651                 .addIfaceValues(TEST_IFACE, 0L, 0L, 0L, 0L);
    652 
    653         {
    654             expectCurrentTime();
    655             expect(mConnManager.getAllNetworkState()).andReturn(state).atLeastOnce();
    656             expect(mStatsService.getNetworkTotalBytes(sTemplateWifi, TIME_FEB_15, currentTimeMillis()))
    657                     .andReturn(stats.getTotalBytes()).atLeastOnce();
    658             expectPolicyDataEnable(TYPE_WIFI, true);
    659 
    660             expectClearNotifications();
    661             expectAdvisePersistThreshold();
    662             future = expectMeteredIfacesChanged();
    663 
    664             replay();
    665             setNetworkPolicies(new NetworkPolicy(sTemplateWifi, CYCLE_DAY, TIMEZONE_UTC, 1
    666                     * MB_IN_BYTES, 2 * MB_IN_BYTES, false));
    667             future.get();
    668             verifyAndReset();
    669         }
    670 
    671         // bring up wifi network
    672         incrementCurrentTime(MINUTE_IN_MILLIS);
    673         state = new NetworkState[] { buildWifi() };
    674         stats = new NetworkStats(getElapsedRealtime(), 1)
    675                 .addIfaceValues(TEST_IFACE, 0L, 0L, 0L, 0L);
    676 
    677         {
    678             expectCurrentTime();
    679             expect(mConnManager.getAllNetworkState()).andReturn(state).atLeastOnce();
    680             expect(mStatsService.getNetworkTotalBytes(sTemplateWifi, TIME_FEB_15, currentTimeMillis()))
    681                     .andReturn(stats.getTotalBytes()).atLeastOnce();
    682             expectPolicyDataEnable(TYPE_WIFI, true);
    683 
    684             expectRemoveInterfaceQuota(TEST_IFACE);
    685             expectSetInterfaceQuota(TEST_IFACE, 2 * MB_IN_BYTES);
    686 
    687             expectClearNotifications();
    688             expectAdvisePersistThreshold();
    689             future = expectMeteredIfacesChanged(TEST_IFACE);
    690 
    691             replay();
    692             mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
    693             future.get();
    694             verifyAndReset();
    695         }
    696 
    697         // go over warning, which should kick notification
    698         incrementCurrentTime(MINUTE_IN_MILLIS);
    699         stats = new NetworkStats(getElapsedRealtime(), 1)
    700                 .addIfaceValues(TEST_IFACE, 1536 * KB_IN_BYTES, 15L, 0L, 0L);
    701 
    702         {
    703             expectCurrentTime();
    704             expect(mStatsService.getNetworkTotalBytes(sTemplateWifi, TIME_FEB_15, currentTimeMillis()))
    705                     .andReturn(stats.getTotalBytes()).atLeastOnce();
    706             expectPolicyDataEnable(TYPE_WIFI, true);
    707 
    708             expectForceUpdate();
    709             expectClearNotifications();
    710             tagFuture = expectEnqueueNotification();
    711 
    712             replay();
    713             mNetworkObserver.limitReached(null, TEST_IFACE);
    714             assertNotificationType(TYPE_WARNING, tagFuture.get());
    715             verifyAndReset();
    716         }
    717 
    718         // go over limit, which should kick notification and dialog
    719         incrementCurrentTime(MINUTE_IN_MILLIS);
    720         stats = new NetworkStats(getElapsedRealtime(), 1)
    721                 .addIfaceValues(TEST_IFACE, 5 * MB_IN_BYTES, 512L, 0L, 0L);
    722 
    723         {
    724             expectCurrentTime();
    725             expect(mStatsService.getNetworkTotalBytes(sTemplateWifi, TIME_FEB_15, currentTimeMillis()))
    726                     .andReturn(stats.getTotalBytes()).atLeastOnce();
    727             expectPolicyDataEnable(TYPE_WIFI, false);
    728 
    729             expectForceUpdate();
    730             expectClearNotifications();
    731             tagFuture = expectEnqueueNotification();
    732 
    733             replay();
    734             mNetworkObserver.limitReached(null, TEST_IFACE);
    735             assertNotificationType(TYPE_LIMIT, tagFuture.get());
    736             verifyAndReset();
    737         }
    738 
    739         // now snooze policy, which should remove quota
    740         incrementCurrentTime(MINUTE_IN_MILLIS);
    741 
    742         {
    743             expectCurrentTime();
    744             expect(mConnManager.getAllNetworkState()).andReturn(state).atLeastOnce();
    745             expect(mStatsService.getNetworkTotalBytes(sTemplateWifi, TIME_FEB_15, currentTimeMillis()))
    746                     .andReturn(stats.getTotalBytes()).atLeastOnce();
    747             expectPolicyDataEnable(TYPE_WIFI, true);
    748 
    749             // snoozed interface still has high quota so background data is
    750             // still restricted.
    751             expectRemoveInterfaceQuota(TEST_IFACE);
    752             expectSetInterfaceQuota(TEST_IFACE, Long.MAX_VALUE);
    753             expectAdvisePersistThreshold();
    754             expectMeteredIfacesChanged(TEST_IFACE);
    755 
    756             future = expectClearNotifications();
    757             tagFuture = expectEnqueueNotification();
    758 
    759             replay();
    760             mService.snoozeLimit(sTemplateWifi);
    761             assertNotificationType(TYPE_LIMIT_SNOOZED, tagFuture.get());
    762             future.get();
    763             verifyAndReset();
    764         }
    765     }
    766 
    767     public void testMeteredNetworkWithoutLimit() throws Exception {
    768         NetworkState[] state = null;
    769         NetworkStats stats = null;
    770         Future<Void> future;
    771         Future<String> tagFuture;
    772 
    773         final long TIME_FEB_15 = 1171497600000L;
    774         final long TIME_MAR_10 = 1173484800000L;
    775         final int CYCLE_DAY = 15;
    776 
    777         setCurrentTimeMillis(TIME_MAR_10);
    778 
    779         // bring up wifi network with metered policy
    780         state = new NetworkState[] { buildWifi() };
    781         stats = new NetworkStats(getElapsedRealtime(), 1)
    782                 .addIfaceValues(TEST_IFACE, 0L, 0L, 0L, 0L);
    783 
    784         {
    785             expectCurrentTime();
    786             expect(mConnManager.getAllNetworkState()).andReturn(state).atLeastOnce();
    787             expect(mStatsService.getNetworkTotalBytes(sTemplateWifi, TIME_FEB_15, currentTimeMillis()))
    788                     .andReturn(stats.getTotalBytes()).atLeastOnce();
    789             expectPolicyDataEnable(TYPE_WIFI, true);
    790 
    791             expectRemoveInterfaceQuota(TEST_IFACE);
    792             expectSetInterfaceQuota(TEST_IFACE, Long.MAX_VALUE);
    793 
    794             expectClearNotifications();
    795             expectAdvisePersistThreshold();
    796             future = expectMeteredIfacesChanged(TEST_IFACE);
    797 
    798             replay();
    799             setNetworkPolicies(new NetworkPolicy(
    800                     sTemplateWifi, CYCLE_DAY, TIMEZONE_UTC, WARNING_DISABLED, LIMIT_DISABLED,
    801                     true));
    802             future.get();
    803             verifyAndReset();
    804         }
    805     }
    806 
    807     private static long parseTime(String time) {
    808         final Time result = new Time();
    809         result.parse3339(time);
    810         return result.toMillis(true);
    811     }
    812 
    813     private void setNetworkPolicies(NetworkPolicy... policies) {
    814         mService.setNetworkPolicies(policies);
    815     }
    816 
    817     private static NetworkState buildWifi() {
    818         final NetworkInfo info = new NetworkInfo(TYPE_WIFI, 0, null, null);
    819         info.setDetailedState(DetailedState.CONNECTED, null, null);
    820         final LinkProperties prop = new LinkProperties();
    821         prop.setInterfaceName(TEST_IFACE);
    822         return new NetworkState(info, prop, null, null, TEST_SSID);
    823     }
    824 
    825     private void expectCurrentTime() throws Exception {
    826         expect(mTime.forceRefresh()).andReturn(false).anyTimes();
    827         expect(mTime.hasCache()).andReturn(true).anyTimes();
    828         expect(mTime.currentTimeMillis()).andReturn(currentTimeMillis()).anyTimes();
    829         expect(mTime.getCacheAge()).andReturn(0L).anyTimes();
    830         expect(mTime.getCacheCertainty()).andReturn(0L).anyTimes();
    831     }
    832 
    833     private void expectForceUpdate() throws Exception {
    834         mStatsService.forceUpdate();
    835         expectLastCall().atLeastOnce();
    836     }
    837 
    838     private Future<Void> expectClearNotifications() throws Exception {
    839         final FutureAnswer future = new FutureAnswer();
    840         mNotifManager.cancelNotificationWithTag(
    841                 isA(String.class), isA(String.class), anyInt(), anyInt());
    842         expectLastCall().andAnswer(future).anyTimes();
    843         return future;
    844     }
    845 
    846     private Future<String> expectEnqueueNotification() throws Exception {
    847         final FutureCapture<String> tag = new FutureCapture<String>();
    848         mNotifManager.enqueueNotificationWithTag(isA(String.class), capture(tag.capture), anyInt(),
    849                 isA(Notification.class), isA(int[].class), UserHandle.myUserId());
    850         return tag;
    851     }
    852 
    853     private void expectSetInterfaceQuota(String iface, long quotaBytes) throws Exception {
    854         mNetworkManager.setInterfaceQuota(iface, quotaBytes);
    855         expectLastCall().atLeastOnce();
    856     }
    857 
    858     private void expectRemoveInterfaceQuota(String iface) throws Exception {
    859         mNetworkManager.removeInterfaceQuota(iface);
    860         expectLastCall().atLeastOnce();
    861     }
    862 
    863     private void expectSetInterfaceAlert(String iface, long alertBytes) throws Exception {
    864         mNetworkManager.setInterfaceAlert(iface, alertBytes);
    865         expectLastCall().atLeastOnce();
    866     }
    867 
    868     private void expectRemoveInterfaceAlert(String iface) throws Exception {
    869         mNetworkManager.removeInterfaceAlert(iface);
    870         expectLastCall().atLeastOnce();
    871     }
    872 
    873     private void expectSetUidNetworkRules(int uid, boolean rejectOnQuotaInterfaces)
    874             throws Exception {
    875         mNetworkManager.setUidNetworkRules(uid, rejectOnQuotaInterfaces);
    876         expectLastCall().atLeastOnce();
    877     }
    878 
    879     private void expectSetUidForeground(int uid, boolean uidForeground) throws Exception {
    880         mStatsService.setUidForeground(uid, uidForeground);
    881         expectLastCall().atLeastOnce();
    882     }
    883 
    884     private Future<Void> expectRulesChanged(int uid, int policy) throws Exception {
    885         final FutureAnswer future = new FutureAnswer();
    886         mPolicyListener.onUidRulesChanged(eq(uid), eq(policy));
    887         expectLastCall().andAnswer(future);
    888         return future;
    889     }
    890 
    891     private Future<Void> expectMeteredIfacesChanged(String... ifaces) throws Exception {
    892         final FutureAnswer future = new FutureAnswer();
    893         mPolicyListener.onMeteredIfacesChanged(aryEq(ifaces));
    894         expectLastCall().andAnswer(future);
    895         return future;
    896     }
    897 
    898     private Future<Void> expectPolicyDataEnable(int type, boolean enabled) throws Exception {
    899         final FutureAnswer future = new FutureAnswer();
    900         mConnManager.setPolicyDataEnable(type, enabled);
    901         expectLastCall().andAnswer(future);
    902         return future;
    903     }
    904 
    905     private void expectAdvisePersistThreshold() throws Exception {
    906         mStatsService.advisePersistThreshold(anyLong());
    907         expectLastCall().anyTimes();
    908     }
    909 
    910     private static class TestAbstractFuture<T> extends AbstractFuture<T> {
    911         @Override
    912         public T get() throws InterruptedException, ExecutionException {
    913             try {
    914                 return get(5, TimeUnit.SECONDS);
    915             } catch (TimeoutException e) {
    916                 throw new RuntimeException(e);
    917             }
    918         }
    919     }
    920 
    921     private static class FutureAnswer extends TestAbstractFuture<Void> implements IAnswer<Void> {
    922         @Override
    923         public Void answer() {
    924             set(null);
    925             return null;
    926         }
    927     }
    928 
    929     private static class FutureCapture<T> extends TestAbstractFuture<T> {
    930         public Capture<T> capture = new Capture<T>() {
    931             @Override
    932             public void setValue(T value) {
    933                 super.setValue(value);
    934                 set(value);
    935             }
    936         };
    937     }
    938 
    939     private static class IdleFuture extends AbstractFuture<Void> implements IdleHandler {
    940         @Override
    941         public Void get() throws InterruptedException, ExecutionException {
    942             try {
    943                 return get(5, TimeUnit.SECONDS);
    944             } catch (TimeoutException e) {
    945                 throw new RuntimeException(e);
    946             }
    947         }
    948 
    949         @Override
    950         public boolean queueIdle() {
    951             set(null);
    952             return false;
    953         }
    954     }
    955 
    956     /**
    957      * Wait until {@link #mService} internal {@link Handler} is idle.
    958      */
    959     private IdleFuture expectIdle() {
    960         final IdleFuture future = new IdleFuture();
    961         mService.addIdleHandler(future);
    962         return future;
    963     }
    964 
    965     private static void assertTimeEquals(long expected, long actual) {
    966         if (expected != actual) {
    967             fail("expected " + formatTime(expected) + " but was actually " + formatTime(actual));
    968         }
    969     }
    970 
    971     private static String formatTime(long millis) {
    972         final Time time = new Time(Time.TIMEZONE_UTC);
    973         time.set(millis);
    974         return time.format3339(false);
    975     }
    976 
    977     private static void assertEqualsFuzzy(long expected, long actual, long fuzzy) {
    978         final long low = expected - fuzzy;
    979         final long high = expected + fuzzy;
    980         if (actual < low || actual > high) {
    981             fail("value " + actual + " is outside [" + low + "," + high + "]");
    982         }
    983     }
    984 
    985     private static void assertUnique(LinkedHashSet<Long> seen, Long value) {
    986         if (!seen.add(value)) {
    987             fail("found duplicate time " + value + " in series " + seen.toString());
    988         }
    989     }
    990 
    991     private static void assertNotificationType(int expected, String actualTag) {
    992         assertEquals(
    993                 Integer.toString(expected), actualTag.substring(actualTag.lastIndexOf(':') + 1));
    994     }
    995 
    996     private long getElapsedRealtime() {
    997         return mElapsedRealtime;
    998     }
    999 
   1000     private void setCurrentTimeMillis(long currentTimeMillis) {
   1001         mStartTime = currentTimeMillis;
   1002         mElapsedRealtime = 0L;
   1003     }
   1004 
   1005     private long currentTimeMillis() {
   1006         return mStartTime + mElapsedRealtime;
   1007     }
   1008 
   1009     private void incrementCurrentTime(long duration) {
   1010         mElapsedRealtime += duration;
   1011     }
   1012 
   1013     private void replay() {
   1014         EasyMock.replay(mActivityManager, mPowerManager, mStatsService, mPolicyListener,
   1015                 mNetworkManager, mTime, mConnManager, mNotifManager);
   1016     }
   1017 
   1018     private void verifyAndReset() {
   1019         EasyMock.verify(mActivityManager, mPowerManager, mStatsService, mPolicyListener,
   1020                 mNetworkManager, mTime, mConnManager, mNotifManager);
   1021         EasyMock.reset(mActivityManager, mPowerManager, mStatsService, mPolicyListener,
   1022                 mNetworkManager, mTime, mConnManager, mNotifManager);
   1023     }
   1024 }
   1025