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