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 testCycleTodayJanuary() throws Exception {
    561         final NetworkPolicy policy = new NetworkPolicy(
    562                 sTemplateWifi, 14, "US/Pacific", 1024L, 1024L, false);
    563 
    564         assertTimeEquals(parseTime("2013-01-14T00:00:00.000-08:00"),
    565                 computeNextCycleBoundary(parseTime("2013-01-13T23:59:59.000-08:00"), policy));
    566         assertTimeEquals(parseTime("2013-02-14T00:00:00.000-08:00"),
    567                 computeNextCycleBoundary(parseTime("2013-01-14T00:00:01.000-08:00"), policy));
    568         assertTimeEquals(parseTime("2013-02-14T00:00:00.000-08:00"),
    569                 computeNextCycleBoundary(parseTime("2013-01-14T15:11:00.000-08:00"), policy));
    570 
    571         assertTimeEquals(parseTime("2012-12-14T00:00:00.000-08:00"),
    572                 computeLastCycleBoundary(parseTime("2013-01-13T23:59:59.000-08:00"), policy));
    573         assertTimeEquals(parseTime("2013-01-14T00:00:00.000-08:00"),
    574                 computeLastCycleBoundary(parseTime("2013-01-14T00:00:01.000-08:00"), policy));
    575         assertTimeEquals(parseTime("2013-01-14T00:00:00.000-08:00"),
    576                 computeLastCycleBoundary(parseTime("2013-01-14T15:11:00.000-08:00"), policy));
    577     }
    578 
    579     public void testNetworkPolicyAppliedCycleLastMonth() throws Exception {
    580         NetworkState[] state = null;
    581         NetworkStats stats = null;
    582         Future<Void> future;
    583 
    584         final long TIME_FEB_15 = 1171497600000L;
    585         final long TIME_MAR_10 = 1173484800000L;
    586         final int CYCLE_DAY = 15;
    587 
    588         setCurrentTimeMillis(TIME_MAR_10);
    589 
    590         // first, pretend that wifi network comes online. no policy active,
    591         // which means we shouldn't push limit to interface.
    592         state = new NetworkState[] { buildWifi() };
    593         expect(mConnManager.getAllNetworkState()).andReturn(state).atLeastOnce();
    594         expectCurrentTime();
    595         expectClearNotifications();
    596         expectAdvisePersistThreshold();
    597         future = expectMeteredIfacesChanged();
    598 
    599         replay();
    600         mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
    601         future.get();
    602         verifyAndReset();
    603 
    604         // now change cycle to be on 15th, and test in early march, to verify we
    605         // pick cycle day in previous month.
    606         expect(mConnManager.getAllNetworkState()).andReturn(state).atLeastOnce();
    607         expectCurrentTime();
    608 
    609         // pretend that 512 bytes total have happened
    610         stats = new NetworkStats(getElapsedRealtime(), 1)
    611                 .addIfaceValues(TEST_IFACE, 256L, 2L, 256L, 2L);
    612         expect(mStatsService.getNetworkTotalBytes(sTemplateWifi, TIME_FEB_15, TIME_MAR_10))
    613                 .andReturn(stats.getTotalBytes()).atLeastOnce();
    614         expectPolicyDataEnable(TYPE_WIFI, true);
    615 
    616         // TODO: consider making strongly ordered mock
    617         expectRemoveInterfaceQuota(TEST_IFACE);
    618         expectSetInterfaceQuota(TEST_IFACE, (2 * MB_IN_BYTES) - 512);
    619 
    620         expectClearNotifications();
    621         expectAdvisePersistThreshold();
    622         future = expectMeteredIfacesChanged(TEST_IFACE);
    623 
    624         replay();
    625         setNetworkPolicies(new NetworkPolicy(
    626                 sTemplateWifi, CYCLE_DAY, TIMEZONE_UTC, 1 * MB_IN_BYTES, 2 * MB_IN_BYTES, false));
    627         future.get();
    628         verifyAndReset();
    629     }
    630 
    631     public void testUidRemovedPolicyCleared() throws Exception {
    632         Future<Void> future;
    633 
    634         // POLICY_REJECT should RULE_REJECT in background
    635         expectSetUidNetworkRules(UID_A, true);
    636         expectSetUidForeground(UID_A, false);
    637         future = expectRulesChanged(UID_A, RULE_REJECT_METERED);
    638         replay();
    639         mService.setUidPolicy(APP_ID_A, POLICY_REJECT_METERED_BACKGROUND);
    640         future.get();
    641         verifyAndReset();
    642 
    643         // uninstall should clear RULE_REJECT
    644         expectSetUidNetworkRules(UID_A, false);
    645         expectSetUidForeground(UID_A, false);
    646         future = expectRulesChanged(UID_A, RULE_ALLOW_ALL);
    647         replay();
    648         final Intent intent = new Intent(ACTION_UID_REMOVED);
    649         intent.putExtra(EXTRA_UID, UID_A);
    650         mServiceContext.sendBroadcast(intent);
    651         future.get();
    652         verifyAndReset();
    653     }
    654 
    655     public void testOverWarningLimitNotification() throws Exception {
    656         NetworkState[] state = null;
    657         NetworkStats stats = null;
    658         Future<Void> future;
    659         Future<String> tagFuture;
    660 
    661         final long TIME_FEB_15 = 1171497600000L;
    662         final long TIME_MAR_10 = 1173484800000L;
    663         final int CYCLE_DAY = 15;
    664 
    665         setCurrentTimeMillis(TIME_MAR_10);
    666 
    667         // assign wifi policy
    668         state = new NetworkState[] {};
    669         stats = new NetworkStats(getElapsedRealtime(), 1)
    670                 .addIfaceValues(TEST_IFACE, 0L, 0L, 0L, 0L);
    671 
    672         {
    673             expectCurrentTime();
    674             expect(mConnManager.getAllNetworkState()).andReturn(state).atLeastOnce();
    675             expect(mStatsService.getNetworkTotalBytes(sTemplateWifi, TIME_FEB_15, currentTimeMillis()))
    676                     .andReturn(stats.getTotalBytes()).atLeastOnce();
    677             expectPolicyDataEnable(TYPE_WIFI, true);
    678 
    679             expectClearNotifications();
    680             expectAdvisePersistThreshold();
    681             future = expectMeteredIfacesChanged();
    682 
    683             replay();
    684             setNetworkPolicies(new NetworkPolicy(sTemplateWifi, CYCLE_DAY, TIMEZONE_UTC, 1
    685                     * MB_IN_BYTES, 2 * MB_IN_BYTES, false));
    686             future.get();
    687             verifyAndReset();
    688         }
    689 
    690         // bring up wifi network
    691         incrementCurrentTime(MINUTE_IN_MILLIS);
    692         state = new NetworkState[] { buildWifi() };
    693         stats = new NetworkStats(getElapsedRealtime(), 1)
    694                 .addIfaceValues(TEST_IFACE, 0L, 0L, 0L, 0L);
    695 
    696         {
    697             expectCurrentTime();
    698             expect(mConnManager.getAllNetworkState()).andReturn(state).atLeastOnce();
    699             expect(mStatsService.getNetworkTotalBytes(sTemplateWifi, TIME_FEB_15, currentTimeMillis()))
    700                     .andReturn(stats.getTotalBytes()).atLeastOnce();
    701             expectPolicyDataEnable(TYPE_WIFI, true);
    702 
    703             expectRemoveInterfaceQuota(TEST_IFACE);
    704             expectSetInterfaceQuota(TEST_IFACE, 2 * MB_IN_BYTES);
    705 
    706             expectClearNotifications();
    707             expectAdvisePersistThreshold();
    708             future = expectMeteredIfacesChanged(TEST_IFACE);
    709 
    710             replay();
    711             mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
    712             future.get();
    713             verifyAndReset();
    714         }
    715 
    716         // go over warning, which should kick notification
    717         incrementCurrentTime(MINUTE_IN_MILLIS);
    718         stats = new NetworkStats(getElapsedRealtime(), 1)
    719                 .addIfaceValues(TEST_IFACE, 1536 * KB_IN_BYTES, 15L, 0L, 0L);
    720 
    721         {
    722             expectCurrentTime();
    723             expect(mStatsService.getNetworkTotalBytes(sTemplateWifi, TIME_FEB_15, currentTimeMillis()))
    724                     .andReturn(stats.getTotalBytes()).atLeastOnce();
    725             expectPolicyDataEnable(TYPE_WIFI, true);
    726 
    727             expectForceUpdate();
    728             expectClearNotifications();
    729             tagFuture = expectEnqueueNotification();
    730 
    731             replay();
    732             mNetworkObserver.limitReached(null, TEST_IFACE);
    733             assertNotificationType(TYPE_WARNING, tagFuture.get());
    734             verifyAndReset();
    735         }
    736 
    737         // go over limit, which should kick notification and dialog
    738         incrementCurrentTime(MINUTE_IN_MILLIS);
    739         stats = new NetworkStats(getElapsedRealtime(), 1)
    740                 .addIfaceValues(TEST_IFACE, 5 * MB_IN_BYTES, 512L, 0L, 0L);
    741 
    742         {
    743             expectCurrentTime();
    744             expect(mStatsService.getNetworkTotalBytes(sTemplateWifi, TIME_FEB_15, currentTimeMillis()))
    745                     .andReturn(stats.getTotalBytes()).atLeastOnce();
    746             expectPolicyDataEnable(TYPE_WIFI, false);
    747 
    748             expectForceUpdate();
    749             expectClearNotifications();
    750             tagFuture = expectEnqueueNotification();
    751 
    752             replay();
    753             mNetworkObserver.limitReached(null, TEST_IFACE);
    754             assertNotificationType(TYPE_LIMIT, tagFuture.get());
    755             verifyAndReset();
    756         }
    757 
    758         // now snooze policy, which should remove quota
    759         incrementCurrentTime(MINUTE_IN_MILLIS);
    760 
    761         {
    762             expectCurrentTime();
    763             expect(mConnManager.getAllNetworkState()).andReturn(state).atLeastOnce();
    764             expect(mStatsService.getNetworkTotalBytes(sTemplateWifi, TIME_FEB_15, currentTimeMillis()))
    765                     .andReturn(stats.getTotalBytes()).atLeastOnce();
    766             expectPolicyDataEnable(TYPE_WIFI, true);
    767 
    768             // snoozed interface still has high quota so background data is
    769             // still restricted.
    770             expectRemoveInterfaceQuota(TEST_IFACE);
    771             expectSetInterfaceQuota(TEST_IFACE, Long.MAX_VALUE);
    772             expectAdvisePersistThreshold();
    773             expectMeteredIfacesChanged(TEST_IFACE);
    774 
    775             future = expectClearNotifications();
    776             tagFuture = expectEnqueueNotification();
    777 
    778             replay();
    779             mService.snoozeLimit(sTemplateWifi);
    780             assertNotificationType(TYPE_LIMIT_SNOOZED, tagFuture.get());
    781             future.get();
    782             verifyAndReset();
    783         }
    784     }
    785 
    786     public void testMeteredNetworkWithoutLimit() throws Exception {
    787         NetworkState[] state = null;
    788         NetworkStats stats = null;
    789         Future<Void> future;
    790         Future<String> tagFuture;
    791 
    792         final long TIME_FEB_15 = 1171497600000L;
    793         final long TIME_MAR_10 = 1173484800000L;
    794         final int CYCLE_DAY = 15;
    795 
    796         setCurrentTimeMillis(TIME_MAR_10);
    797 
    798         // bring up wifi network with metered policy
    799         state = new NetworkState[] { buildWifi() };
    800         stats = new NetworkStats(getElapsedRealtime(), 1)
    801                 .addIfaceValues(TEST_IFACE, 0L, 0L, 0L, 0L);
    802 
    803         {
    804             expectCurrentTime();
    805             expect(mConnManager.getAllNetworkState()).andReturn(state).atLeastOnce();
    806             expect(mStatsService.getNetworkTotalBytes(sTemplateWifi, TIME_FEB_15, currentTimeMillis()))
    807                     .andReturn(stats.getTotalBytes()).atLeastOnce();
    808             expectPolicyDataEnable(TYPE_WIFI, true);
    809 
    810             expectRemoveInterfaceQuota(TEST_IFACE);
    811             expectSetInterfaceQuota(TEST_IFACE, Long.MAX_VALUE);
    812 
    813             expectClearNotifications();
    814             expectAdvisePersistThreshold();
    815             future = expectMeteredIfacesChanged(TEST_IFACE);
    816 
    817             replay();
    818             setNetworkPolicies(new NetworkPolicy(
    819                     sTemplateWifi, CYCLE_DAY, TIMEZONE_UTC, WARNING_DISABLED, LIMIT_DISABLED,
    820                     true));
    821             future.get();
    822             verifyAndReset();
    823         }
    824     }
    825 
    826     private static long parseTime(String time) {
    827         final Time result = new Time();
    828         result.parse3339(time);
    829         return result.toMillis(true);
    830     }
    831 
    832     private void setNetworkPolicies(NetworkPolicy... policies) {
    833         mService.setNetworkPolicies(policies);
    834     }
    835 
    836     private static NetworkState buildWifi() {
    837         final NetworkInfo info = new NetworkInfo(TYPE_WIFI, 0, null, null);
    838         info.setDetailedState(DetailedState.CONNECTED, null, null);
    839         final LinkProperties prop = new LinkProperties();
    840         prop.setInterfaceName(TEST_IFACE);
    841         return new NetworkState(info, prop, null, null, TEST_SSID);
    842     }
    843 
    844     private void expectCurrentTime() throws Exception {
    845         expect(mTime.forceRefresh()).andReturn(false).anyTimes();
    846         expect(mTime.hasCache()).andReturn(true).anyTimes();
    847         expect(mTime.currentTimeMillis()).andReturn(currentTimeMillis()).anyTimes();
    848         expect(mTime.getCacheAge()).andReturn(0L).anyTimes();
    849         expect(mTime.getCacheCertainty()).andReturn(0L).anyTimes();
    850     }
    851 
    852     private void expectForceUpdate() throws Exception {
    853         mStatsService.forceUpdate();
    854         expectLastCall().atLeastOnce();
    855     }
    856 
    857     private Future<Void> expectClearNotifications() throws Exception {
    858         final FutureAnswer future = new FutureAnswer();
    859         mNotifManager.cancelNotificationWithTag(
    860                 isA(String.class), isA(String.class), anyInt(), anyInt());
    861         expectLastCall().andAnswer(future).anyTimes();
    862         return future;
    863     }
    864 
    865     private Future<String> expectEnqueueNotification() throws Exception {
    866         final FutureCapture<String> tag = new FutureCapture<String>();
    867         mNotifManager.enqueueNotificationWithTag(isA(String.class), isA(String.class),
    868                 capture(tag.capture), anyInt(),
    869                 isA(Notification.class), isA(int[].class), UserHandle.myUserId());
    870         return tag;
    871     }
    872 
    873     private void expectSetInterfaceQuota(String iface, long quotaBytes) throws Exception {
    874         mNetworkManager.setInterfaceQuota(iface, quotaBytes);
    875         expectLastCall().atLeastOnce();
    876     }
    877 
    878     private void expectRemoveInterfaceQuota(String iface) throws Exception {
    879         mNetworkManager.removeInterfaceQuota(iface);
    880         expectLastCall().atLeastOnce();
    881     }
    882 
    883     private void expectSetInterfaceAlert(String iface, long alertBytes) throws Exception {
    884         mNetworkManager.setInterfaceAlert(iface, alertBytes);
    885         expectLastCall().atLeastOnce();
    886     }
    887 
    888     private void expectRemoveInterfaceAlert(String iface) throws Exception {
    889         mNetworkManager.removeInterfaceAlert(iface);
    890         expectLastCall().atLeastOnce();
    891     }
    892 
    893     private void expectSetUidNetworkRules(int uid, boolean rejectOnQuotaInterfaces)
    894             throws Exception {
    895         mNetworkManager.setUidNetworkRules(uid, rejectOnQuotaInterfaces);
    896         expectLastCall().atLeastOnce();
    897     }
    898 
    899     private void expectSetUidForeground(int uid, boolean uidForeground) throws Exception {
    900         mStatsService.setUidForeground(uid, uidForeground);
    901         expectLastCall().atLeastOnce();
    902     }
    903 
    904     private Future<Void> expectRulesChanged(int uid, int policy) throws Exception {
    905         final FutureAnswer future = new FutureAnswer();
    906         mPolicyListener.onUidRulesChanged(eq(uid), eq(policy));
    907         expectLastCall().andAnswer(future);
    908         return future;
    909     }
    910 
    911     private Future<Void> expectMeteredIfacesChanged(String... ifaces) throws Exception {
    912         final FutureAnswer future = new FutureAnswer();
    913         mPolicyListener.onMeteredIfacesChanged(aryEq(ifaces));
    914         expectLastCall().andAnswer(future);
    915         return future;
    916     }
    917 
    918     private Future<Void> expectPolicyDataEnable(int type, boolean enabled) throws Exception {
    919         final FutureAnswer future = new FutureAnswer();
    920         mConnManager.setPolicyDataEnable(type, enabled);
    921         expectLastCall().andAnswer(future);
    922         return future;
    923     }
    924 
    925     private void expectAdvisePersistThreshold() throws Exception {
    926         mStatsService.advisePersistThreshold(anyLong());
    927         expectLastCall().anyTimes();
    928     }
    929 
    930     private static class TestAbstractFuture<T> extends AbstractFuture<T> {
    931         @Override
    932         public T get() throws InterruptedException, ExecutionException {
    933             try {
    934                 return get(5, TimeUnit.SECONDS);
    935             } catch (TimeoutException e) {
    936                 throw new RuntimeException(e);
    937             }
    938         }
    939     }
    940 
    941     private static class FutureAnswer extends TestAbstractFuture<Void> implements IAnswer<Void> {
    942         @Override
    943         public Void answer() {
    944             set(null);
    945             return null;
    946         }
    947     }
    948 
    949     private static class FutureCapture<T> extends TestAbstractFuture<T> {
    950         public Capture<T> capture = new Capture<T>() {
    951             @Override
    952             public void setValue(T value) {
    953                 super.setValue(value);
    954                 set(value);
    955             }
    956         };
    957     }
    958 
    959     private static class IdleFuture extends AbstractFuture<Void> implements IdleHandler {
    960         @Override
    961         public Void get() throws InterruptedException, ExecutionException {
    962             try {
    963                 return get(5, TimeUnit.SECONDS);
    964             } catch (TimeoutException e) {
    965                 throw new RuntimeException(e);
    966             }
    967         }
    968 
    969         @Override
    970         public boolean queueIdle() {
    971             set(null);
    972             return false;
    973         }
    974     }
    975 
    976     /**
    977      * Wait until {@link #mService} internal {@link Handler} is idle.
    978      */
    979     private IdleFuture expectIdle() {
    980         final IdleFuture future = new IdleFuture();
    981         mService.addIdleHandler(future);
    982         return future;
    983     }
    984 
    985     private static void assertTimeEquals(long expected, long actual) {
    986         if (expected != actual) {
    987             fail("expected " + formatTime(expected) + " but was actually " + formatTime(actual));
    988         }
    989     }
    990 
    991     private static String formatTime(long millis) {
    992         final Time time = new Time(Time.TIMEZONE_UTC);
    993         time.set(millis);
    994         return time.format3339(false);
    995     }
    996 
    997     private static void assertEqualsFuzzy(long expected, long actual, long fuzzy) {
    998         final long low = expected - fuzzy;
    999         final long high = expected + fuzzy;
   1000         if (actual < low || actual > high) {
   1001             fail("value " + actual + " is outside [" + low + "," + high + "]");
   1002         }
   1003     }
   1004 
   1005     private static void assertUnique(LinkedHashSet<Long> seen, Long value) {
   1006         if (!seen.add(value)) {
   1007             fail("found duplicate time " + value + " in series " + seen.toString());
   1008         }
   1009     }
   1010 
   1011     private static void assertNotificationType(int expected, String actualTag) {
   1012         assertEquals(
   1013                 Integer.toString(expected), actualTag.substring(actualTag.lastIndexOf(':') + 1));
   1014     }
   1015 
   1016     private long getElapsedRealtime() {
   1017         return mElapsedRealtime;
   1018     }
   1019 
   1020     private void setCurrentTimeMillis(long currentTimeMillis) {
   1021         mStartTime = currentTimeMillis;
   1022         mElapsedRealtime = 0L;
   1023     }
   1024 
   1025     private long currentTimeMillis() {
   1026         return mStartTime + mElapsedRealtime;
   1027     }
   1028 
   1029     private void incrementCurrentTime(long duration) {
   1030         mElapsedRealtime += duration;
   1031     }
   1032 
   1033     private void replay() {
   1034         EasyMock.replay(mActivityManager, mPowerManager, mStatsService, mPolicyListener,
   1035                 mNetworkManager, mTime, mConnManager, mNotifManager);
   1036     }
   1037 
   1038     private void verifyAndReset() {
   1039         EasyMock.verify(mActivityManager, mPowerManager, mStatsService, mPolicyListener,
   1040                 mNetworkManager, mTime, mConnManager, mNotifManager);
   1041         EasyMock.reset(mActivityManager, mPowerManager, mStatsService, mPolicyListener,
   1042                 mNetworkManager, mTime, mConnManager, mNotifManager);
   1043     }
   1044 }
   1045