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