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