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