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