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