NetworkStatsServiceTest.java revision fe46a2f8689f96e75c491d5c2477fe2caec2f289
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.net;
18
19import static android.content.Intent.ACTION_UID_REMOVED;
20import static android.content.Intent.EXTRA_UID;
21import static android.net.ConnectivityManager.TYPE_MOBILE;
22import static android.net.ConnectivityManager.TYPE_WIFI;
23import static android.net.ConnectivityManager.TYPE_WIMAX;
24import static android.net.NetworkStats.IFACE_ALL;
25import static android.net.NetworkStats.ROAMING_ALL;
26import static android.net.NetworkStats.ROAMING_NO;
27import static android.net.NetworkStats.ROAMING_YES;
28import static android.net.NetworkStats.SET_ALL;
29import static android.net.NetworkStats.SET_DEFAULT;
30import static android.net.NetworkStats.SET_FOREGROUND;
31import static android.net.NetworkStats.TAG_NONE;
32import static android.net.NetworkStats.UID_ALL;
33import static android.net.NetworkStatsHistory.FIELD_ALL;
34import static android.net.NetworkTemplate.buildTemplateMobileAll;
35import static android.net.NetworkTemplate.buildTemplateWifiWildcard;
36import static android.net.TrafficStats.MB_IN_BYTES;
37import static android.net.TrafficStats.UID_REMOVED;
38import static android.net.TrafficStats.UID_TETHERING;
39import static android.text.format.DateUtils.DAY_IN_MILLIS;
40import static android.text.format.DateUtils.HOUR_IN_MILLIS;
41import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
42import static android.text.format.DateUtils.WEEK_IN_MILLIS;
43
44import static com.android.server.net.NetworkStatsService.ACTION_NETWORK_STATS_POLL;
45
46import static org.easymock.EasyMock.anyInt;
47import static org.easymock.EasyMock.anyLong;
48import static org.easymock.EasyMock.anyObject;
49import static org.easymock.EasyMock.capture;
50import static org.easymock.EasyMock.createMock;
51import static org.easymock.EasyMock.eq;
52import static org.easymock.EasyMock.expect;
53import static org.easymock.EasyMock.expectLastCall;
54import static org.junit.Assert.assertEquals;
55import static org.junit.Assert.assertNull;
56import static org.junit.Assert.assertTrue;
57import static org.junit.Assert.fail;
58
59import android.app.AlarmManager;
60import android.app.usage.NetworkStatsManager;
61import android.content.Context;
62import android.content.Intent;
63import android.net.DataUsageRequest;
64import android.net.IConnectivityManager;
65import android.net.INetworkManagementEventObserver;
66import android.net.INetworkStatsSession;
67import android.net.LinkProperties;
68import android.net.NetworkCapabilities;
69import android.net.NetworkInfo;
70import android.net.NetworkInfo.DetailedState;
71import android.net.NetworkState;
72import android.net.NetworkStats;
73import android.net.NetworkStatsHistory;
74import android.net.NetworkTemplate;
75import android.os.ConditionVariable;
76import android.os.Handler;
77import android.os.HandlerThread;
78import android.os.INetworkManagementService;
79import android.os.IBinder;
80import android.os.Looper;
81import android.os.Messenger;
82import android.os.MessageQueue;
83import android.os.MessageQueue.IdleHandler;
84import android.os.Message;
85import android.os.PowerManager;
86import android.support.test.InstrumentationRegistry;
87import android.support.test.runner.AndroidJUnit4;
88import android.telephony.TelephonyManager;
89import android.test.AndroidTestCase;
90import android.util.TrustedTime;
91
92import com.android.internal.net.VpnInfo;
93import com.android.internal.util.test.BroadcastInterceptingContext;
94import com.android.server.net.NetworkStatsService;
95import com.android.server.net.NetworkStatsService.NetworkStatsSettings;
96import com.android.server.net.NetworkStatsService.NetworkStatsSettings.Config;
97
98import libcore.io.IoUtils;
99
100import org.easymock.Capture;
101import org.easymock.EasyMock;
102import org.junit.After;
103import org.junit.Before;
104import org.junit.Test;
105import org.junit.runner.RunWith;
106
107import java.io.File;
108import java.util.ArrayList;
109import java.util.Objects;
110import java.util.List;
111
112/**
113 * Tests for {@link NetworkStatsService}.
114 *
115 * TODO: This test is really brittle, largely due to overly-strict use of Easymock.
116 * Rewrite w/ Mockito.
117 */
118@RunWith(AndroidJUnit4.class)
119public class NetworkStatsServiceTest {
120    private static final String TAG = "NetworkStatsServiceTest";
121
122    private static final String TEST_IFACE = "test0";
123    private static final String TEST_IFACE2 = "test1";
124    private static final long TEST_START = 1194220800000L;
125
126    private static final String IMSI_1 = "310004";
127    private static final String IMSI_2 = "310260";
128    private static final String TEST_SSID = "AndroidAP";
129
130    private static NetworkTemplate sTemplateWifi = buildTemplateWifiWildcard();
131    private static NetworkTemplate sTemplateImsi1 = buildTemplateMobileAll(IMSI_1);
132    private static NetworkTemplate sTemplateImsi2 = buildTemplateMobileAll(IMSI_2);
133
134    private static final int UID_RED = 1001;
135    private static final int UID_BLUE = 1002;
136    private static final int UID_GREEN = 1003;
137
138    private static final long WAIT_TIMEOUT = 2 * 1000;  // 2 secs
139    private static final int INVALID_TYPE = -1;
140
141    private long mElapsedRealtime;
142
143    private BroadcastInterceptingContext mServiceContext;
144    private File mStatsDir;
145
146    private INetworkManagementService mNetManager;
147    private TrustedTime mTime;
148    private NetworkStatsSettings mSettings;
149    private IConnectivityManager mConnManager;
150    private IdleableHandlerThread mHandlerThread;
151    private Handler mHandler;
152
153    private NetworkStatsService mService;
154    private INetworkStatsSession mSession;
155    private INetworkManagementEventObserver mNetworkObserver;
156
157    @Before
158    public void setUp() throws Exception {
159        final Context context = InstrumentationRegistry.getContext();
160
161        mServiceContext = new BroadcastInterceptingContext(context);
162        mStatsDir = context.getFilesDir();
163        if (mStatsDir.exists()) {
164            IoUtils.deleteContents(mStatsDir);
165        }
166
167        mNetManager = createMock(INetworkManagementService.class);
168
169        // TODO: Mock AlarmManager when migrating this test to Mockito.
170        AlarmManager alarmManager = (AlarmManager) mServiceContext
171                .getSystemService(Context.ALARM_SERVICE);
172        mTime = createMock(TrustedTime.class);
173        mSettings = createMock(NetworkStatsSettings.class);
174        mConnManager = createMock(IConnectivityManager.class);
175
176        PowerManager powerManager = (PowerManager) mServiceContext.getSystemService(
177                Context.POWER_SERVICE);
178        PowerManager.WakeLock wakeLock =
179                powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
180
181        mService = new NetworkStatsService(
182                mServiceContext, mNetManager, alarmManager, wakeLock, mTime,
183                TelephonyManager.getDefault(), mSettings, new NetworkStatsObservers(),
184                mStatsDir, getBaseDir(mStatsDir));
185        mHandlerThread = new IdleableHandlerThread("HandlerThread");
186        mHandlerThread.start();
187        Handler.Callback callback = new NetworkStatsService.HandlerCallback(mService);
188        mHandler = new Handler(mHandlerThread.getLooper(), callback);
189        mService.setHandler(mHandler, callback);
190        mService.bindConnectivityManager(mConnManager);
191
192        mElapsedRealtime = 0L;
193
194        expectCurrentTime();
195        expectDefaultSettings();
196        expectNetworkStatsUidDetail(buildEmptyStats());
197        expectSystemReady();
198
199        // catch INetworkManagementEventObserver during systemReady()
200        final Capture<INetworkManagementEventObserver> networkObserver = new Capture<
201                INetworkManagementEventObserver>();
202        mNetManager.registerObserver(capture(networkObserver));
203        expectLastCall().atLeastOnce();
204
205        replay();
206        mService.systemReady();
207        mSession = mService.openSession();
208        verifyAndReset();
209
210        mNetworkObserver = networkObserver.getValue();
211
212    }
213
214    @After
215    public void tearDown() throws Exception {
216        IoUtils.deleteContents(mStatsDir);
217
218        mServiceContext = null;
219        mStatsDir = null;
220
221        mNetManager = null;
222        mTime = null;
223        mSettings = null;
224        mConnManager = null;
225
226        mSession.close();
227        mService = null;
228    }
229
230    @Test
231    public void testNetworkStatsWifi() throws Exception {
232        // pretend that wifi network comes online; service should ask about full
233        // network state, and poll any existing interfaces before updating.
234        expectCurrentTime();
235        expectDefaultSettings();
236        expectNetworkState(buildWifiState());
237        expectNetworkStatsSummary(buildEmptyStats());
238        expectNetworkStatsUidDetail(buildEmptyStats());
239        expectNetworkStatsPoll();
240        expectBandwidthControlCheck();
241
242        replay();
243        mService.forceUpdateIfaces();
244
245        // verify service has empty history for wifi
246        assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
247        verifyAndReset();
248
249        // modify some number on wifi, and trigger poll event
250        incrementCurrentTime(HOUR_IN_MILLIS);
251        expectCurrentTime();
252        expectDefaultSettings();
253        expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
254                .addIfaceValues(TEST_IFACE, 1024L, 1L, 2048L, 2L));
255        expectNetworkStatsUidDetail(buildEmptyStats());
256        expectNetworkStatsPoll();
257
258        replay();
259        forcePollAndWaitForIdle();
260
261        // verify service recorded history
262        assertNetworkTotal(sTemplateWifi, 1024L, 1L, 2048L, 2L, 0);
263        verifyAndReset();
264
265        // and bump forward again, with counters going higher. this is
266        // important, since polling should correctly subtract last snapshot.
267        incrementCurrentTime(DAY_IN_MILLIS);
268        expectCurrentTime();
269        expectDefaultSettings();
270        expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
271                .addIfaceValues(TEST_IFACE, 4096L, 4L, 8192L, 8L));
272        expectNetworkStatsUidDetail(buildEmptyStats());
273        expectNetworkStatsPoll();
274
275        replay();
276        forcePollAndWaitForIdle();
277
278        // verify service recorded history
279        assertNetworkTotal(sTemplateWifi, 4096L, 4L, 8192L, 8L, 0);
280        verifyAndReset();
281
282    }
283
284    @Test
285    public void testStatsRebootPersist() throws Exception {
286        assertStatsFilesExist(false);
287
288        // pretend that wifi network comes online; service should ask about full
289        // network state, and poll any existing interfaces before updating.
290        expectCurrentTime();
291        expectDefaultSettings();
292        expectNetworkState(buildWifiState());
293        expectNetworkStatsSummary(buildEmptyStats());
294        expectNetworkStatsUidDetail(buildEmptyStats());
295        expectNetworkStatsPoll();
296        expectBandwidthControlCheck();
297
298        replay();
299        mService.forceUpdateIfaces();
300
301        // verify service has empty history for wifi
302        assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
303        verifyAndReset();
304
305        // modify some number on wifi, and trigger poll event
306        incrementCurrentTime(HOUR_IN_MILLIS);
307        expectCurrentTime();
308        expectDefaultSettings();
309        expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
310                .addIfaceValues(TEST_IFACE, 1024L, 8L, 2048L, 16L));
311        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 2)
312                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 512L, 4L, 256L, 2L, 0L)
313                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xFAAD, 256L, 2L, 128L, 1L, 0L)
314                .addValues(TEST_IFACE, UID_RED, SET_FOREGROUND, TAG_NONE, 512L, 4L, 256L, 2L, 0L)
315                .addValues(TEST_IFACE, UID_RED, SET_FOREGROUND, 0xFAAD, 256L, 2L, 128L, 1L, 0L)
316                .addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 128L, 1L, 128L, 1L, 0L));
317        expectNetworkStatsPoll();
318
319        mService.setUidForeground(UID_RED, false);
320        mService.incrementOperationCount(UID_RED, 0xFAAD, 4);
321        mService.setUidForeground(UID_RED, true);
322        mService.incrementOperationCount(UID_RED, 0xFAAD, 6);
323
324        replay();
325        forcePollAndWaitForIdle();
326
327        // verify service recorded history
328        assertNetworkTotal(sTemplateWifi, 1024L, 8L, 2048L, 16L, 0);
329        assertUidTotal(sTemplateWifi, UID_RED, 1024L, 8L, 512L, 4L, 10);
330        assertUidTotal(sTemplateWifi, UID_RED, SET_DEFAULT, ROAMING_NO, 512L, 4L, 256L, 2L, 4);
331        assertUidTotal(sTemplateWifi, UID_RED, SET_FOREGROUND, ROAMING_NO, 512L, 4L, 256L, 2L,
332                6);
333        assertUidTotal(sTemplateWifi, UID_BLUE, 128L, 1L, 128L, 1L, 0);
334        verifyAndReset();
335
336        // graceful shutdown system, which should trigger persist of stats, and
337        // clear any values in memory.
338        expectCurrentTime();
339        expectDefaultSettings();
340        replay();
341        mServiceContext.sendBroadcast(new Intent(Intent.ACTION_SHUTDOWN));
342        verifyAndReset();
343
344        assertStatsFilesExist(true);
345
346        // boot through serviceReady() again
347        expectCurrentTime();
348        expectDefaultSettings();
349        expectNetworkStatsUidDetail(buildEmptyStats());
350        expectSystemReady();
351
352        // catch INetworkManagementEventObserver during systemReady()
353        final Capture<INetworkManagementEventObserver> networkObserver = new Capture<
354                INetworkManagementEventObserver>();
355        mNetManager.registerObserver(capture(networkObserver));
356        expectLastCall().atLeastOnce();
357
358        replay();
359        mService.systemReady();
360
361        mNetworkObserver = networkObserver.getValue();
362
363        // after systemReady(), we should have historical stats loaded again
364        assertNetworkTotal(sTemplateWifi, 1024L, 8L, 2048L, 16L, 0);
365        assertUidTotal(sTemplateWifi, UID_RED, 1024L, 8L, 512L, 4L, 10);
366        assertUidTotal(sTemplateWifi, UID_RED, SET_DEFAULT, ROAMING_NO, 512L, 4L, 256L, 2L, 4);
367        assertUidTotal(sTemplateWifi, UID_RED, SET_FOREGROUND, ROAMING_NO, 512L, 4L, 256L, 2L,
368                6);
369        assertUidTotal(sTemplateWifi, UID_BLUE, 128L, 1L, 128L, 1L, 0);
370        verifyAndReset();
371
372    }
373
374    // TODO: simulate reboot to test bucket resize
375    // @Test
376    public void testStatsBucketResize() throws Exception {
377        NetworkStatsHistory history = null;
378
379        assertStatsFilesExist(false);
380
381        // pretend that wifi network comes online; service should ask about full
382        // network state, and poll any existing interfaces before updating.
383        expectCurrentTime();
384        expectSettings(0L, HOUR_IN_MILLIS, WEEK_IN_MILLIS);
385        expectNetworkState(buildWifiState());
386        expectNetworkStatsSummary(buildEmptyStats());
387        expectNetworkStatsUidDetail(buildEmptyStats());
388        expectNetworkStatsPoll();
389        expectBandwidthControlCheck();
390
391        replay();
392        mService.forceUpdateIfaces();
393        verifyAndReset();
394
395        // modify some number on wifi, and trigger poll event
396        incrementCurrentTime(2 * HOUR_IN_MILLIS);
397        expectCurrentTime();
398        expectSettings(0L, HOUR_IN_MILLIS, WEEK_IN_MILLIS);
399        expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
400                .addIfaceValues(TEST_IFACE, 512L, 4L, 512L, 4L));
401        expectNetworkStatsUidDetail(buildEmptyStats());
402        expectNetworkStatsPoll();
403
404        replay();
405        forcePollAndWaitForIdle();
406
407        // verify service recorded history
408        history = mSession.getHistoryForNetwork(sTemplateWifi, FIELD_ALL);
409        assertValues(history, Long.MIN_VALUE, Long.MAX_VALUE, 512L, 4L, 512L, 4L, 0);
410        assertEquals(HOUR_IN_MILLIS, history.getBucketDuration());
411        assertEquals(2, history.size());
412        verifyAndReset();
413
414        // now change bucket duration setting and trigger another poll with
415        // exact same values, which should resize existing buckets.
416        expectCurrentTime();
417        expectSettings(0L, 30 * MINUTE_IN_MILLIS, WEEK_IN_MILLIS);
418        expectNetworkStatsSummary(buildEmptyStats());
419        expectNetworkStatsUidDetail(buildEmptyStats());
420        expectNetworkStatsPoll();
421
422        replay();
423        forcePollAndWaitForIdle();
424
425        // verify identical stats, but spread across 4 buckets now
426        history = mSession.getHistoryForNetwork(sTemplateWifi, FIELD_ALL);
427        assertValues(history, Long.MIN_VALUE, Long.MAX_VALUE, 512L, 4L, 512L, 4L, 0);
428        assertEquals(30 * MINUTE_IN_MILLIS, history.getBucketDuration());
429        assertEquals(4, history.size());
430        verifyAndReset();
431
432    }
433
434    @Test
435    public void testUidStatsAcrossNetworks() throws Exception {
436        // pretend first mobile network comes online
437        expectCurrentTime();
438        expectDefaultSettings();
439        expectNetworkState(buildMobile3gState(IMSI_1));
440        expectNetworkStatsSummary(buildEmptyStats());
441        expectNetworkStatsUidDetail(buildEmptyStats());
442        expectNetworkStatsPoll();
443        expectBandwidthControlCheck();
444
445        replay();
446        mService.forceUpdateIfaces();
447        verifyAndReset();
448
449        // create some traffic on first network
450        incrementCurrentTime(HOUR_IN_MILLIS);
451        expectCurrentTime();
452        expectDefaultSettings();
453        expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
454                .addIfaceValues(TEST_IFACE, 2048L, 16L, 512L, 4L));
455        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 3)
456                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1536L, 12L, 512L, 4L, 0L)
457                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)
458                .addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 512L, 4L, 0L, 0L, 0L));
459        expectNetworkStatsPoll();
460
461        mService.incrementOperationCount(UID_RED, 0xF00D, 10);
462
463        replay();
464        forcePollAndWaitForIdle();
465
466        // verify service recorded history
467        assertNetworkTotal(sTemplateImsi1, 2048L, 16L, 512L, 4L, 0);
468        assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
469        assertUidTotal(sTemplateImsi1, UID_RED, 1536L, 12L, 512L, 4L, 10);
470        assertUidTotal(sTemplateImsi1, UID_BLUE, 512L, 4L, 0L, 0L, 0);
471        verifyAndReset();
472
473        // now switch networks; this also tests that we're okay with interfaces
474        // disappearing, to verify we don't count backwards.
475        incrementCurrentTime(HOUR_IN_MILLIS);
476        expectCurrentTime();
477        expectDefaultSettings();
478        expectNetworkState(buildMobile3gState(IMSI_2));
479        expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
480                .addIfaceValues(TEST_IFACE, 2048L, 16L, 512L, 4L));
481        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 3)
482                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1536L, 12L, 512L, 4L, 0L)
483                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)
484                .addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 512L, 4L, 0L, 0L, 0L));
485        expectNetworkStatsPoll();
486        expectBandwidthControlCheck();
487
488        replay();
489        mService.forceUpdateIfaces();
490        forcePollAndWaitForIdle();
491        verifyAndReset();
492
493        // create traffic on second network
494        incrementCurrentTime(HOUR_IN_MILLIS);
495        expectCurrentTime();
496        expectDefaultSettings();
497        expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
498                .addIfaceValues(TEST_IFACE, 2176L, 17L, 1536L, 12L));
499        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
500                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1536L, 12L, 512L, 4L, 0L)
501                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)
502                .addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 640L, 5L, 1024L, 8L, 0L)
503                .addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, 0xFAAD, 128L, 1L, 1024L, 8L, 0L));
504        expectNetworkStatsPoll();
505
506        mService.incrementOperationCount(UID_BLUE, 0xFAAD, 10);
507
508        replay();
509        forcePollAndWaitForIdle();
510
511        // verify original history still intact
512        assertNetworkTotal(sTemplateImsi1, 2048L, 16L, 512L, 4L, 0);
513        assertUidTotal(sTemplateImsi1, UID_RED, 1536L, 12L, 512L, 4L, 10);
514        assertUidTotal(sTemplateImsi1, UID_BLUE, 512L, 4L, 0L, 0L, 0);
515
516        // and verify new history also recorded under different template, which
517        // verifies that we didn't cross the streams.
518        assertNetworkTotal(sTemplateImsi2, 128L, 1L, 1024L, 8L, 0);
519        assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
520        assertUidTotal(sTemplateImsi2, UID_BLUE, 128L, 1L, 1024L, 8L, 10);
521        verifyAndReset();
522
523    }
524
525    @Test
526    public void testUidRemovedIsMoved() throws Exception {
527        // pretend that network comes online
528        expectCurrentTime();
529        expectDefaultSettings();
530        expectNetworkState(buildWifiState());
531        expectNetworkStatsSummary(buildEmptyStats());
532        expectNetworkStatsUidDetail(buildEmptyStats());
533        expectNetworkStatsPoll();
534        expectBandwidthControlCheck();
535
536        replay();
537        mService.forceUpdateIfaces();
538        verifyAndReset();
539
540        // create some traffic
541        incrementCurrentTime(HOUR_IN_MILLIS);
542        expectCurrentTime();
543        expectDefaultSettings();
544        expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
545                .addIfaceValues(TEST_IFACE, 4128L, 258L, 544L, 34L));
546        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
547                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L)
548                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xFAAD, 16L, 1L, 16L, 1L, 0L)
549                .addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 4096L, 258L, 512L, 32L, 0L)
550                .addValues(TEST_IFACE, UID_GREEN, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L));
551        expectNetworkStatsPoll();
552
553        mService.incrementOperationCount(UID_RED, 0xFAAD, 10);
554
555        replay();
556        forcePollAndWaitForIdle();
557
558        // verify service recorded history
559        assertNetworkTotal(sTemplateWifi, 4128L, 258L, 544L, 34L, 0);
560        assertUidTotal(sTemplateWifi, UID_RED, 16L, 1L, 16L, 1L, 10);
561        assertUidTotal(sTemplateWifi, UID_BLUE, 4096L, 258L, 512L, 32L, 0);
562        assertUidTotal(sTemplateWifi, UID_GREEN, 16L, 1L, 16L, 1L, 0);
563        verifyAndReset();
564
565        // now pretend two UIDs are uninstalled, which should migrate stats to
566        // special "removed" bucket.
567        expectCurrentTime();
568        expectDefaultSettings();
569        expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
570                .addIfaceValues(TEST_IFACE, 4128L, 258L, 544L, 34L));
571        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
572                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L)
573                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xFAAD, 16L, 1L, 16L, 1L, 0L)
574                .addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 4096L, 258L, 512L, 32L, 0L)
575                .addValues(TEST_IFACE, UID_GREEN, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L));
576        expectNetworkStatsPoll();
577
578        replay();
579        final Intent intent = new Intent(ACTION_UID_REMOVED);
580        intent.putExtra(EXTRA_UID, UID_BLUE);
581        mServiceContext.sendBroadcast(intent);
582        intent.putExtra(EXTRA_UID, UID_RED);
583        mServiceContext.sendBroadcast(intent);
584
585        // existing uid and total should remain unchanged; but removed UID
586        // should be gone completely.
587        assertNetworkTotal(sTemplateWifi, 4128L, 258L, 544L, 34L, 0);
588        assertUidTotal(sTemplateWifi, UID_RED, 0L, 0L, 0L, 0L, 0);
589        assertUidTotal(sTemplateWifi, UID_BLUE, 0L, 0L, 0L, 0L, 0);
590        assertUidTotal(sTemplateWifi, UID_GREEN, 16L, 1L, 16L, 1L, 0);
591        assertUidTotal(sTemplateWifi, UID_REMOVED, 4112L, 259L, 528L, 33L, 10);
592        verifyAndReset();
593
594    }
595
596    @Test
597    public void testUid3g4gCombinedByTemplate() throws Exception {
598        // pretend that network comes online
599        expectCurrentTime();
600        expectDefaultSettings();
601        expectNetworkState(buildMobile3gState(IMSI_1));
602        expectNetworkStatsSummary(buildEmptyStats());
603        expectNetworkStatsUidDetail(buildEmptyStats());
604        expectNetworkStatsPoll();
605        expectBandwidthControlCheck();
606
607        replay();
608        mService.forceUpdateIfaces();
609        verifyAndReset();
610
611        // create some traffic
612        incrementCurrentTime(HOUR_IN_MILLIS);
613        expectCurrentTime();
614        expectDefaultSettings();
615        expectNetworkStatsSummary(buildEmptyStats());
616        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
617                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 0L)
618                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L));
619        expectNetworkStatsPoll();
620
621        mService.incrementOperationCount(UID_RED, 0xF00D, 5);
622
623        replay();
624        forcePollAndWaitForIdle();
625
626        // verify service recorded history
627        assertUidTotal(sTemplateImsi1, UID_RED, 1024L, 8L, 1024L, 8L, 5);
628        verifyAndReset();
629
630        // now switch over to 4g network
631        incrementCurrentTime(HOUR_IN_MILLIS);
632        expectCurrentTime();
633        expectDefaultSettings();
634        expectNetworkState(buildMobile4gState(TEST_IFACE2));
635        expectNetworkStatsSummary(buildEmptyStats());
636        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
637                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 0L)
638                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L));
639        expectNetworkStatsPoll();
640        expectBandwidthControlCheck();
641
642        replay();
643        mService.forceUpdateIfaces();
644        forcePollAndWaitForIdle();
645        verifyAndReset();
646
647        // create traffic on second network
648        incrementCurrentTime(HOUR_IN_MILLIS);
649        expectCurrentTime();
650        expectDefaultSettings();
651        expectNetworkStatsSummary(buildEmptyStats());
652        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
653                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 0L)
654                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)
655                .addValues(TEST_IFACE2, UID_RED, SET_DEFAULT, TAG_NONE, 512L, 4L, 256L, 2L, 0L)
656                .addValues(TEST_IFACE2, UID_RED, SET_DEFAULT, 0xFAAD, 512L, 4L, 256L, 2L, 0L));
657        expectNetworkStatsPoll();
658
659        mService.incrementOperationCount(UID_RED, 0xFAAD, 5);
660
661        replay();
662        forcePollAndWaitForIdle();
663
664        // verify that ALL_MOBILE template combines both
665        assertUidTotal(sTemplateImsi1, UID_RED, 1536L, 12L, 1280L, 10L, 10);
666
667        verifyAndReset();
668    }
669
670    @Test
671    public void testSummaryForAllUid() throws Exception {
672        // pretend that network comes online
673        expectCurrentTime();
674        expectDefaultSettings();
675        expectNetworkState(buildWifiState());
676        expectNetworkStatsSummary(buildEmptyStats());
677        expectNetworkStatsUidDetail(buildEmptyStats());
678        expectNetworkStatsPoll();
679        expectBandwidthControlCheck();
680
681        replay();
682        mService.forceUpdateIfaces();
683        verifyAndReset();
684
685        // create some traffic for two apps
686        incrementCurrentTime(HOUR_IN_MILLIS);
687        expectCurrentTime();
688        expectDefaultSettings();
689        expectNetworkStatsSummary(buildEmptyStats());
690        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
691                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 50L, 5L, 50L, 5L, 0L)
692                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 10L, 1L, 10L, 1L, 0L)
693                .addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 1024L, 8L, 512L, 4L, 0L));
694        expectNetworkStatsPoll();
695
696        mService.incrementOperationCount(UID_RED, 0xF00D, 1);
697
698        replay();
699        forcePollAndWaitForIdle();
700
701        // verify service recorded history
702        assertUidTotal(sTemplateWifi, UID_RED, 50L, 5L, 50L, 5L, 1);
703        assertUidTotal(sTemplateWifi, UID_BLUE, 1024L, 8L, 512L, 4L, 0);
704        verifyAndReset();
705
706        // now create more traffic in next hour, but only for one app
707        incrementCurrentTime(HOUR_IN_MILLIS);
708        expectCurrentTime();
709        expectDefaultSettings();
710        expectNetworkStatsSummary(buildEmptyStats());
711        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
712                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 50L, 5L, 50L, 5L, 0L)
713                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 10L, 1L, 10L, 1L, 0L)
714                .addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 2048L, 16L, 1024L, 8L, 0L));
715        expectNetworkStatsPoll();
716
717        replay();
718        forcePollAndWaitForIdle();
719
720        // first verify entire history present
721        NetworkStats stats = mSession.getSummaryForAllUid(
722                sTemplateWifi, Long.MIN_VALUE, Long.MAX_VALUE, true);
723        assertEquals(3, stats.size());
724        assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_NO, 50L, 5L,
725                50L, 5L, 1);
726        assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, 0xF00D, ROAMING_NO, 10L, 1L, 10L,
727                1L, 1);
728        assertValues(stats, IFACE_ALL, UID_BLUE, SET_DEFAULT, TAG_NONE, ROAMING_NO, 2048L, 16L,
729                1024L, 8L, 0);
730
731        // now verify that recent history only contains one uid
732        final long currentTime = currentTimeMillis();
733        stats = mSession.getSummaryForAllUid(
734                sTemplateWifi, currentTime - HOUR_IN_MILLIS, currentTime, true);
735        assertEquals(1, stats.size());
736        assertValues(stats, IFACE_ALL, UID_BLUE, SET_DEFAULT, TAG_NONE, ROAMING_NO, 1024L, 8L,
737                512L, 4L, 0);
738
739        verifyAndReset();
740    }
741
742    @Test
743    public void testForegroundBackground() throws Exception {
744        // pretend that network comes online
745        expectCurrentTime();
746        expectDefaultSettings();
747        expectNetworkState(buildWifiState());
748        expectNetworkStatsSummary(buildEmptyStats());
749        expectNetworkStatsUidDetail(buildEmptyStats());
750        expectNetworkStatsPoll();
751        expectBandwidthControlCheck();
752
753        replay();
754        mService.forceUpdateIfaces();
755        verifyAndReset();
756
757        // create some initial traffic
758        incrementCurrentTime(HOUR_IN_MILLIS);
759        expectCurrentTime();
760        expectDefaultSettings();
761        expectNetworkStatsSummary(buildEmptyStats());
762        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
763                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L)
764                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 64L, 1L, 64L, 1L, 0L));
765        expectNetworkStatsPoll();
766
767        mService.incrementOperationCount(UID_RED, 0xF00D, 1);
768
769        replay();
770        forcePollAndWaitForIdle();
771
772        // verify service recorded history
773        assertUidTotal(sTemplateWifi, UID_RED, 128L, 2L, 128L, 2L, 1);
774        verifyAndReset();
775
776        // now switch to foreground
777        incrementCurrentTime(HOUR_IN_MILLIS);
778        expectCurrentTime();
779        expectDefaultSettings();
780        expectNetworkStatsSummary(buildEmptyStats());
781        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
782                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L)
783                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 64L, 1L, 64L, 1L, 0L)
784                .addValues(TEST_IFACE, UID_RED, SET_FOREGROUND, TAG_NONE, 32L, 2L, 32L, 2L, 0L)
785                .addValues(TEST_IFACE, UID_RED, SET_FOREGROUND, 0xFAAD, 1L, 1L, 1L, 1L, 0L));
786        expectNetworkStatsPoll();
787
788        mService.setUidForeground(UID_RED, true);
789        mService.incrementOperationCount(UID_RED, 0xFAAD, 1);
790
791        replay();
792        forcePollAndWaitForIdle();
793
794        // test that we combined correctly
795        assertUidTotal(sTemplateWifi, UID_RED, 160L, 4L, 160L, 4L, 2);
796
797        // verify entire history present
798        final NetworkStats stats = mSession.getSummaryForAllUid(
799                sTemplateWifi, Long.MIN_VALUE, Long.MAX_VALUE, true);
800        assertEquals(4, stats.size());
801        assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_NO, 128L, 2L,
802                128L, 2L, 1);
803        assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, 0xF00D, ROAMING_NO, 64L, 1L, 64L,
804                1L, 1);
805        assertValues(stats, IFACE_ALL, UID_RED, SET_FOREGROUND, TAG_NONE, ROAMING_NO, 32L, 2L,
806                32L, 2L, 1);
807        assertValues(stats, IFACE_ALL, UID_RED, SET_FOREGROUND, 0xFAAD, ROAMING_NO, 1L, 1L, 1L,
808                1L, 1);
809
810        verifyAndReset();
811    }
812
813    @Test
814    public void testRoaming() throws Exception {
815        // pretend that network comes online
816        expectCurrentTime();
817        expectDefaultSettings();
818        expectNetworkState(buildMobile3gState(IMSI_1, true /* isRoaming */));
819        expectNetworkStatsSummary(buildEmptyStats());
820        expectNetworkStatsUidDetail(buildEmptyStats());
821        expectNetworkStatsPoll();
822        expectBandwidthControlCheck();
823
824        replay();
825        mService.forceUpdateIfaces();
826        verifyAndReset();
827
828        // Create some traffic
829        incrementCurrentTime(HOUR_IN_MILLIS);
830        expectCurrentTime();
831        expectDefaultSettings();
832        expectNetworkStatsSummary(buildEmptyStats());
833        // Note that all traffic from NetworkManagementService is tagged as ROAMING_NO, because
834        // roaming isn't tracked at that layer. We layer it on top by inspecting the iface
835        // properties.
836        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
837                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_NO, 128L, 2L,
838                        128L, 2L, 0L)
839                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, ROAMING_NO, 64L, 1L, 64L,
840                        1L, 0L));
841        expectNetworkStatsPoll();
842
843        replay();
844        forcePollAndWaitForIdle();
845
846        // verify service recorded history
847        assertUidTotal(sTemplateImsi1, UID_RED, 128L, 2L, 128L, 2L, 0);
848
849        // verify entire history present
850        final NetworkStats stats = mSession.getSummaryForAllUid(
851                sTemplateImsi1, Long.MIN_VALUE, Long.MAX_VALUE, true);
852        assertEquals(2, stats.size());
853        assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_YES, 128L, 2L,
854                128L, 2L, 0);
855        assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, 0xF00D, ROAMING_YES, 64L, 1L, 64L,
856                1L, 0);
857
858        verifyAndReset();
859    }
860
861    @Test
862    public void testTethering() throws Exception {
863        // pretend first mobile network comes online
864        expectCurrentTime();
865        expectDefaultSettings();
866        expectNetworkState(buildMobile3gState(IMSI_1));
867        expectNetworkStatsSummary(buildEmptyStats());
868        expectNetworkStatsUidDetail(buildEmptyStats());
869        expectNetworkStatsPoll();
870        expectBandwidthControlCheck();
871
872        replay();
873        mService.forceUpdateIfaces();
874        verifyAndReset();
875
876        // create some tethering traffic
877        incrementCurrentTime(HOUR_IN_MILLIS);
878        expectCurrentTime();
879        expectDefaultSettings();
880        expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
881                .addIfaceValues(TEST_IFACE, 2048L, 16L, 512L, 4L));
882
883        final NetworkStats uidStats = new NetworkStats(getElapsedRealtime(), 1)
884                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L);
885        final String[] tetherIfacePairs = new String[] { TEST_IFACE, "wlan0" };
886        final NetworkStats tetherStats = new NetworkStats(getElapsedRealtime(), 1)
887                .addValues(TEST_IFACE, UID_TETHERING, SET_DEFAULT, TAG_NONE, 1920L, 14L, 384L, 2L, 0L);
888
889        expectNetworkStatsUidDetail(uidStats, tetherIfacePairs, tetherStats);
890        expectNetworkStatsPoll();
891
892        replay();
893        forcePollAndWaitForIdle();
894
895        // verify service recorded history
896        assertNetworkTotal(sTemplateImsi1, 2048L, 16L, 512L, 4L, 0);
897        assertUidTotal(sTemplateImsi1, UID_RED, 128L, 2L, 128L, 2L, 0);
898        assertUidTotal(sTemplateImsi1, UID_TETHERING, 1920L, 14L, 384L, 2L, 0);
899        verifyAndReset();
900
901    }
902
903    @Test
904    public void testRegisterUsageCallback() throws Exception {
905        // pretend that wifi network comes online; service should ask about full
906        // network state, and poll any existing interfaces before updating.
907        expectCurrentTime();
908        expectDefaultSettings();
909        expectNetworkState(buildWifiState());
910        expectNetworkStatsSummary(buildEmptyStats());
911        expectNetworkStatsUidDetail(buildEmptyStats());
912        expectNetworkStatsPoll();
913        expectBandwidthControlCheck();
914
915        replay();
916        mService.forceUpdateIfaces();
917
918        // verify service has empty history for wifi
919        assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
920        verifyAndReset();
921
922        String callingPackage = "the.calling.package";
923        long thresholdInBytes = 1L;  // very small; should be overriden by framework
924        DataUsageRequest inputRequest = new DataUsageRequest(
925                DataUsageRequest.REQUEST_ID_UNSET, sTemplateWifi, thresholdInBytes);
926
927        // Create a messenger that waits for callback activity
928        ConditionVariable cv = new ConditionVariable(false);
929        LatchedHandler latchedHandler = new LatchedHandler(Looper.getMainLooper(), cv);
930        Messenger messenger = new Messenger(latchedHandler);
931
932        // Allow binder to connect
933        IBinder mockBinder = createMock(IBinder.class);
934        mockBinder.linkToDeath((IBinder.DeathRecipient) anyObject(), anyInt());
935        EasyMock.replay(mockBinder);
936
937        // Force poll
938        expectCurrentTime();
939        expectDefaultSettings();
940        expectNetworkStatsSummary(buildEmptyStats());
941        expectNetworkStatsUidDetail(buildEmptyStats());
942        expectNetworkStatsPoll();
943        replay();
944
945        // Register and verify request and that binder was called
946        DataUsageRequest request =
947                mService.registerUsageCallback(callingPackage, inputRequest,
948                        messenger, mockBinder);
949        assertTrue(request.requestId > 0);
950        assertTrue(Objects.equals(sTemplateWifi, request.template));
951        long minThresholdInBytes = 2 * 1024 * 1024; // 2 MB
952        assertEquals(minThresholdInBytes, request.thresholdInBytes);
953
954        // Send dummy message to make sure that any previous message has been handled
955        mHandler.sendMessage(mHandler.obtainMessage(-1));
956        mHandlerThread.waitForIdle(WAIT_TIMEOUT);
957
958        verifyAndReset();
959
960        // Make sure that the caller binder gets connected
961        EasyMock.verify(mockBinder);
962        EasyMock.reset(mockBinder);
963
964        // modify some number on wifi, and trigger poll event
965        // not enough traffic to call data usage callback
966        incrementCurrentTime(HOUR_IN_MILLIS);
967        expectCurrentTime();
968        expectDefaultSettings();
969        expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
970                .addIfaceValues(TEST_IFACE, 1024L, 1L, 2048L, 2L));
971        expectNetworkStatsUidDetail(buildEmptyStats());
972        expectNetworkStatsPoll();
973
974        replay();
975        forcePollAndWaitForIdle();
976
977        // verify service recorded history
978        verifyAndReset();
979        assertNetworkTotal(sTemplateWifi, 1024L, 1L, 2048L, 2L, 0);
980
981        // make sure callback has not being called
982        assertEquals(INVALID_TYPE, latchedHandler.mLastMessageType);
983
984        // and bump forward again, with counters going higher. this is
985        // important, since it will trigger the data usage callback
986        incrementCurrentTime(DAY_IN_MILLIS);
987        expectCurrentTime();
988        expectDefaultSettings();
989        expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
990                .addIfaceValues(TEST_IFACE, 4096000L, 4L, 8192000L, 8L));
991        expectNetworkStatsUidDetail(buildEmptyStats());
992        expectNetworkStatsPoll();
993
994        replay();
995        forcePollAndWaitForIdle();
996
997        // verify service recorded history
998        assertNetworkTotal(sTemplateWifi, 4096000L, 4L, 8192000L, 8L, 0);
999        verifyAndReset();
1000
1001        // Wait for the caller to ack receipt of CALLBACK_LIMIT_REACHED
1002        assertTrue(cv.block(WAIT_TIMEOUT));
1003        assertEquals(NetworkStatsManager.CALLBACK_LIMIT_REACHED, latchedHandler.mLastMessageType);
1004        cv.close();
1005
1006        // Allow binder to disconnect
1007        expect(mockBinder.unlinkToDeath((IBinder.DeathRecipient) anyObject(), anyInt()))
1008                .andReturn(true);
1009        EasyMock.replay(mockBinder);
1010
1011        // Unregister request
1012        mService.unregisterUsageRequest(request);
1013
1014        // Wait for the caller to ack receipt of CALLBACK_RELEASED
1015        assertTrue(cv.block(WAIT_TIMEOUT));
1016        assertEquals(NetworkStatsManager.CALLBACK_RELEASED, latchedHandler.mLastMessageType);
1017
1018        // Make sure that the caller binder gets disconnected
1019        EasyMock.verify(mockBinder);
1020    }
1021
1022    @Test
1023    public void testUnregisterUsageCallback_unknown_noop() throws Exception {
1024        String callingPackage = "the.calling.package";
1025        long thresholdInBytes = 10 * 1024 * 1024;  // 10 MB
1026        DataUsageRequest unknownRequest = new DataUsageRequest(
1027                2 /* requestId */, sTemplateImsi1, thresholdInBytes);
1028
1029        mService.unregisterUsageRequest(unknownRequest);
1030    }
1031
1032    private static File getBaseDir(File statsDir) {
1033        File baseDir = new File(statsDir, "netstats");
1034        baseDir.mkdirs();
1035        return baseDir;
1036    }
1037
1038    private void assertNetworkTotal(NetworkTemplate template, long rxBytes, long rxPackets,
1039            long txBytes, long txPackets, int operations) throws Exception {
1040        assertNetworkTotal(template, Long.MIN_VALUE, Long.MAX_VALUE, rxBytes, rxPackets, txBytes,
1041                txPackets, operations);
1042    }
1043
1044    private void assertNetworkTotal(NetworkTemplate template, long start, long end, long rxBytes,
1045            long rxPackets, long txBytes, long txPackets, int operations) throws Exception {
1046        // verify history API
1047        final NetworkStatsHistory history = mSession.getHistoryForNetwork(template, FIELD_ALL);
1048        assertValues(history, start, end, rxBytes, rxPackets, txBytes, txPackets, operations);
1049
1050        // verify summary API
1051        final NetworkStats stats = mSession.getSummaryForNetwork(template, start, end);
1052        assertValues(stats, IFACE_ALL, UID_ALL, SET_DEFAULT, TAG_NONE, ROAMING_NO, rxBytes,
1053                rxPackets, txBytes, txPackets, operations);
1054    }
1055
1056    private void assertUidTotal(NetworkTemplate template, int uid, long rxBytes, long rxPackets,
1057            long txBytes, long txPackets, int operations) throws Exception {
1058        assertUidTotal(template, uid, SET_ALL, ROAMING_ALL, rxBytes, rxPackets, txBytes, txPackets,
1059                operations);
1060    }
1061
1062    private void assertUidTotal(NetworkTemplate template, int uid, int set, int roaming,
1063            long rxBytes, long rxPackets, long txBytes, long txPackets, int operations)
1064            throws Exception {
1065        // verify history API
1066        final NetworkStatsHistory history = mSession.getHistoryForUid(
1067                template, uid, set, TAG_NONE, FIELD_ALL);
1068        assertValues(history, Long.MIN_VALUE, Long.MAX_VALUE, rxBytes, rxPackets, txBytes,
1069                txPackets, operations);
1070
1071        // verify summary API
1072        final NetworkStats stats = mSession.getSummaryForAllUid(
1073                template, Long.MIN_VALUE, Long.MAX_VALUE, false);
1074        assertValues(stats, IFACE_ALL, uid, set, TAG_NONE, roaming, rxBytes, rxPackets, txBytes,
1075                txPackets, operations);
1076    }
1077
1078    private void expectSystemReady() throws Exception {
1079        mNetManager.setGlobalAlert(anyLong());
1080        expectLastCall().atLeastOnce();
1081
1082        expectNetworkStatsSummary(buildEmptyStats());
1083        expectBandwidthControlCheck();
1084    }
1085
1086    private void expectNetworkState(NetworkState... state) throws Exception {
1087        expect(mConnManager.getAllNetworkState()).andReturn(state).atLeastOnce();
1088
1089        final LinkProperties linkProp = state.length > 0 ? state[0].linkProperties : null;
1090        expect(mConnManager.getActiveLinkProperties()).andReturn(linkProp).atLeastOnce();
1091    }
1092
1093    private void expectNetworkStatsSummary(NetworkStats summary) throws Exception {
1094        expect(mConnManager.getAllVpnInfo()).andReturn(new VpnInfo[0]).atLeastOnce();
1095
1096        expectNetworkStatsSummaryDev(summary);
1097        expectNetworkStatsSummaryXt(summary);
1098    }
1099
1100    private void expectNetworkStatsSummaryDev(NetworkStats summary) throws Exception {
1101        expect(mNetManager.getNetworkStatsSummaryDev()).andReturn(summary).atLeastOnce();
1102    }
1103
1104    private void expectNetworkStatsSummaryXt(NetworkStats summary) throws Exception {
1105        expect(mNetManager.getNetworkStatsSummaryXt()).andReturn(summary).atLeastOnce();
1106    }
1107
1108    private void expectNetworkStatsUidDetail(NetworkStats detail) throws Exception {
1109        expectNetworkStatsUidDetail(detail, new String[0], new NetworkStats(0L, 0));
1110    }
1111
1112    private void expectNetworkStatsUidDetail(
1113            NetworkStats detail, String[] tetherIfacePairs, NetworkStats tetherStats)
1114            throws Exception {
1115        expect(mNetManager.getNetworkStatsUidDetail(eq(UID_ALL))).andReturn(detail).atLeastOnce();
1116
1117        // also include tethering details, since they are folded into UID
1118        expect(mNetManager.getNetworkStatsTethering())
1119                .andReturn(tetherStats).atLeastOnce();
1120    }
1121
1122    private void expectDefaultSettings() throws Exception {
1123        expectSettings(0L, HOUR_IN_MILLIS, WEEK_IN_MILLIS);
1124    }
1125
1126    private void expectSettings(long persistBytes, long bucketDuration, long deleteAge)
1127            throws Exception {
1128        expect(mSettings.getPollInterval()).andReturn(HOUR_IN_MILLIS).anyTimes();
1129        expect(mSettings.getTimeCacheMaxAge()).andReturn(DAY_IN_MILLIS).anyTimes();
1130        expect(mSettings.getSampleEnabled()).andReturn(true).anyTimes();
1131
1132        final Config config = new Config(bucketDuration, deleteAge, deleteAge);
1133        expect(mSettings.getDevConfig()).andReturn(config).anyTimes();
1134        expect(mSettings.getXtConfig()).andReturn(config).anyTimes();
1135        expect(mSettings.getUidConfig()).andReturn(config).anyTimes();
1136        expect(mSettings.getUidTagConfig()).andReturn(config).anyTimes();
1137
1138        expect(mSettings.getGlobalAlertBytes(anyLong())).andReturn(MB_IN_BYTES).anyTimes();
1139        expect(mSettings.getDevPersistBytes(anyLong())).andReturn(MB_IN_BYTES).anyTimes();
1140        expect(mSettings.getXtPersistBytes(anyLong())).andReturn(MB_IN_BYTES).anyTimes();
1141        expect(mSettings.getUidPersistBytes(anyLong())).andReturn(MB_IN_BYTES).anyTimes();
1142        expect(mSettings.getUidTagPersistBytes(anyLong())).andReturn(MB_IN_BYTES).anyTimes();
1143    }
1144
1145    private void expectCurrentTime() throws Exception {
1146        expect(mTime.forceRefresh()).andReturn(false).anyTimes();
1147        expect(mTime.hasCache()).andReturn(true).anyTimes();
1148        expect(mTime.currentTimeMillis()).andReturn(currentTimeMillis()).anyTimes();
1149        expect(mTime.getCacheAge()).andReturn(0L).anyTimes();
1150        expect(mTime.getCacheCertainty()).andReturn(0L).anyTimes();
1151    }
1152
1153    private void expectNetworkStatsPoll() throws Exception {
1154        mNetManager.setGlobalAlert(anyLong());
1155        expectLastCall().anyTimes();
1156    }
1157
1158    private void expectBandwidthControlCheck() throws Exception {
1159        expect(mNetManager.isBandwidthControlEnabled()).andReturn(true).atLeastOnce();
1160    }
1161
1162    private void assertStatsFilesExist(boolean exist) {
1163        final File basePath = new File(mStatsDir, "netstats");
1164        if (exist) {
1165            assertTrue(basePath.list().length > 0);
1166        } else {
1167            assertTrue(basePath.list().length == 0);
1168        }
1169    }
1170
1171    private static void assertValues(NetworkStats stats, String iface, int uid, int set,
1172            int tag, int roaming, long rxBytes, long rxPackets, long txBytes, long txPackets,
1173            int operations) {
1174        final NetworkStats.Entry entry = new NetworkStats.Entry();
1175        List<Integer> sets = new ArrayList<>();
1176        if (set == SET_DEFAULT || set == SET_ALL) {
1177            sets.add(SET_DEFAULT);
1178        }
1179        if (set == SET_FOREGROUND || set == SET_ALL) {
1180            sets.add(SET_FOREGROUND);
1181        }
1182
1183        List<Integer> roamings = new ArrayList<>();
1184        if (roaming == ROAMING_NO || roaming == ROAMING_ALL) {
1185            roamings.add(ROAMING_NO);
1186        }
1187        if (roaming == ROAMING_YES || roaming == ROAMING_ALL) {
1188            roamings.add(ROAMING_YES);
1189        }
1190
1191        for (int s : sets) {
1192            for (int r : roamings) {
1193                final int i = stats.findIndex(iface, uid, s, tag, r);
1194                if (i != -1) {
1195                    entry.add(stats.getValues(i, null));
1196                }
1197            }
1198        }
1199
1200        assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes);
1201        assertEquals("unexpected rxPackets", rxPackets, entry.rxPackets);
1202        assertEquals("unexpected txBytes", txBytes, entry.txBytes);
1203        assertEquals("unexpected txPackets", txPackets, entry.txPackets);
1204        assertEquals("unexpected operations", operations, entry.operations);
1205    }
1206
1207    private static void assertValues(NetworkStatsHistory stats, long start, long end, long rxBytes,
1208            long rxPackets, long txBytes, long txPackets, int operations) {
1209        final NetworkStatsHistory.Entry entry = stats.getValues(start, end, null);
1210        assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes);
1211        assertEquals("unexpected rxPackets", rxPackets, entry.rxPackets);
1212        assertEquals("unexpected txBytes", txBytes, entry.txBytes);
1213        assertEquals("unexpected txPackets", txPackets, entry.txPackets);
1214        assertEquals("unexpected operations", operations, entry.operations);
1215    }
1216
1217    private static NetworkState buildWifiState() {
1218        final NetworkInfo info = new NetworkInfo(TYPE_WIFI, 0, null, null);
1219        info.setDetailedState(DetailedState.CONNECTED, null, null);
1220        final LinkProperties prop = new LinkProperties();
1221        prop.setInterfaceName(TEST_IFACE);
1222        final NetworkCapabilities capabilities = new NetworkCapabilities();
1223        return new NetworkState(info, prop, capabilities, null, null, TEST_SSID);
1224    }
1225
1226    private static NetworkState buildMobile3gState(String subscriberId) {
1227        return buildMobile3gState(subscriberId, false /* isRoaming */);
1228    }
1229
1230    private static NetworkState buildMobile3gState(String subscriberId, boolean isRoaming) {
1231        final NetworkInfo info = new NetworkInfo(
1232                TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UMTS, null, null);
1233        info.setDetailedState(DetailedState.CONNECTED, null, null);
1234        info.setRoaming(isRoaming);
1235        final LinkProperties prop = new LinkProperties();
1236        prop.setInterfaceName(TEST_IFACE);
1237        final NetworkCapabilities capabilities = new NetworkCapabilities();
1238        return new NetworkState(info, prop, capabilities, null, subscriberId, null);
1239    }
1240
1241    private static NetworkState buildMobile4gState(String iface) {
1242        final NetworkInfo info = new NetworkInfo(TYPE_WIMAX, 0, null, null);
1243        info.setDetailedState(DetailedState.CONNECTED, null, null);
1244        final LinkProperties prop = new LinkProperties();
1245        prop.setInterfaceName(iface);
1246        final NetworkCapabilities capabilities = new NetworkCapabilities();
1247        return new NetworkState(info, prop, capabilities, null, null, null);
1248    }
1249
1250    private NetworkStats buildEmptyStats() {
1251        return new NetworkStats(getElapsedRealtime(), 0);
1252    }
1253
1254    private long getElapsedRealtime() {
1255        return mElapsedRealtime;
1256    }
1257
1258    private long startTimeMillis() {
1259        return TEST_START;
1260    }
1261
1262    private long currentTimeMillis() {
1263        return startTimeMillis() + mElapsedRealtime;
1264    }
1265
1266    private void incrementCurrentTime(long duration) {
1267        mElapsedRealtime += duration;
1268    }
1269
1270    private void replay() {
1271        EasyMock.replay(mNetManager, mTime, mSettings, mConnManager);
1272    }
1273
1274    private void verifyAndReset() {
1275        EasyMock.verify(mNetManager, mTime, mSettings, mConnManager);
1276        EasyMock.reset(mNetManager, mTime, mSettings, mConnManager);
1277    }
1278
1279    private void forcePollAndWaitForIdle() {
1280        mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
1281        // Send dummy message to make sure that any previous message has been handled
1282        mHandler.sendMessage(mHandler.obtainMessage(-1));
1283        mHandlerThread.waitForIdle(WAIT_TIMEOUT);
1284    }
1285
1286    static class LatchedHandler extends Handler {
1287        private final ConditionVariable mCv;
1288        int mLastMessageType = INVALID_TYPE;
1289
1290        LatchedHandler(Looper looper, ConditionVariable cv) {
1291            super(looper);
1292            mCv = cv;
1293        }
1294
1295        @Override
1296        public void handleMessage(Message msg) {
1297            mLastMessageType = msg.what;
1298            mCv.open();
1299            super.handleMessage(msg);
1300        }
1301    }
1302
1303    /**
1304     * A subclass of HandlerThread that allows callers to wait for it to become idle. waitForIdle
1305     * will return immediately if the handler is already idle.
1306     */
1307    static class IdleableHandlerThread extends HandlerThread {
1308        private IdleHandler mIdleHandler;
1309
1310        public IdleableHandlerThread(String name) {
1311            super(name);
1312        }
1313
1314        public void waitForIdle(long timeoutMs) {
1315            final ConditionVariable cv = new ConditionVariable();
1316            final MessageQueue queue = getLooper().getQueue();
1317
1318            synchronized (queue) {
1319                if (queue.isIdle()) {
1320                    return;
1321                }
1322
1323                assertNull("BUG: only one idle handler allowed", mIdleHandler);
1324                mIdleHandler = new IdleHandler() {
1325                    public boolean queueIdle() {
1326                        cv.open();
1327                        mIdleHandler = null;
1328                        return false;  // Remove the handler.
1329                    }
1330                };
1331                queue.addIdleHandler(mIdleHandler);
1332            }
1333
1334            if (!cv.block(timeoutMs)) {
1335                fail("HandlerThread " + getName() + " did not become idle after " + timeoutMs
1336                        + " ms");
1337                queue.removeIdleHandler(mIdleHandler);
1338            }
1339        }
1340    }
1341
1342}
1343