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