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