NetworkStatsServiceTest.java revision e8914c36276710de50b347c1e6aecfa45d6a56cd
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;
18
19import static android.content.Intent.ACTION_UID_REMOVED;
20import static android.content.Intent.EXTRA_UID;
21import static android.net.ConnectivityManager.CONNECTIVITY_ACTION_IMMEDIATE;
22import static android.net.ConnectivityManager.TYPE_MOBILE;
23import static android.net.ConnectivityManager.TYPE_WIFI;
24import static android.net.ConnectivityManager.TYPE_WIMAX;
25import static android.net.NetworkStats.IFACE_ALL;
26import static android.net.NetworkStats.SET_ALL;
27import static android.net.NetworkStats.SET_DEFAULT;
28import static android.net.NetworkStats.SET_FOREGROUND;
29import static android.net.NetworkStats.TAG_NONE;
30import static android.net.NetworkStats.UID_ALL;
31import static android.net.NetworkStatsHistory.FIELD_ALL;
32import static android.net.NetworkTemplate.buildTemplateMobileAll;
33import static android.net.NetworkTemplate.buildTemplateWifiWildcard;
34import static android.net.TrafficStats.MB_IN_BYTES;
35import static android.net.TrafficStats.UID_REMOVED;
36import static android.net.TrafficStats.UID_TETHERING;
37import static android.text.format.DateUtils.DAY_IN_MILLIS;
38import static android.text.format.DateUtils.HOUR_IN_MILLIS;
39import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
40import static android.text.format.DateUtils.WEEK_IN_MILLIS;
41import static com.android.server.net.NetworkStatsService.ACTION_NETWORK_STATS_POLL;
42import static org.easymock.EasyMock.anyLong;
43import static org.easymock.EasyMock.aryEq;
44import static org.easymock.EasyMock.capture;
45import static org.easymock.EasyMock.createMock;
46import static org.easymock.EasyMock.eq;
47import static org.easymock.EasyMock.expect;
48import static org.easymock.EasyMock.expectLastCall;
49import static org.easymock.EasyMock.isA;
50
51import android.app.AlarmManager;
52import android.app.IAlarmManager;
53import android.app.PendingIntent;
54import android.content.Intent;
55import android.net.IConnectivityManager;
56import android.net.INetworkManagementEventObserver;
57import android.net.INetworkStatsSession;
58import android.net.LinkProperties;
59import android.net.NetworkInfo;
60import android.net.NetworkInfo.DetailedState;
61import android.net.NetworkState;
62import android.net.NetworkStats;
63import android.net.NetworkStatsHistory;
64import android.net.NetworkTemplate;
65import android.os.INetworkManagementService;
66import android.telephony.TelephonyManager;
67import android.test.AndroidTestCase;
68import android.test.suitebuilder.annotation.LargeTest;
69import android.test.suitebuilder.annotation.Suppress;
70import android.util.TrustedTime;
71
72import com.android.server.net.NetworkStatsService;
73import com.android.server.net.NetworkStatsService.NetworkStatsSettings;
74import com.android.server.net.NetworkStatsService.NetworkStatsSettings.Config;
75
76import org.easymock.Capture;
77import org.easymock.EasyMock;
78
79import java.io.File;
80
81import libcore.io.IoUtils;
82
83/**
84 * Tests for {@link NetworkStatsService}.
85 */
86@LargeTest
87public class NetworkStatsServiceTest extends AndroidTestCase {
88    private static final String TAG = "NetworkStatsServiceTest";
89
90    private static final String TEST_IFACE = "test0";
91    private static final String TEST_IFACE2 = "test1";
92    private static final long TEST_START = 1194220800000L;
93
94    private static final String IMSI_1 = "310004";
95    private static final String IMSI_2 = "310260";
96
97    private static NetworkTemplate sTemplateWifi = buildTemplateWifiWildcard();
98    private static NetworkTemplate sTemplateImsi1 = buildTemplateMobileAll(IMSI_1);
99    private static NetworkTemplate sTemplateImsi2 = buildTemplateMobileAll(IMSI_2);
100
101    private static final int UID_RED = 1001;
102    private static final int UID_BLUE = 1002;
103    private static final int UID_GREEN = 1003;
104
105    private long mElapsedRealtime;
106
107    private BroadcastInterceptingContext mServiceContext;
108    private File mStatsDir;
109
110    private INetworkManagementService mNetManager;
111    private IAlarmManager mAlarmManager;
112    private TrustedTime mTime;
113    private NetworkStatsSettings mSettings;
114    private IConnectivityManager mConnManager;
115
116    private NetworkStatsService mService;
117    private INetworkStatsSession mSession;
118    private INetworkManagementEventObserver mNetworkObserver;
119
120    @Override
121    public void setUp() throws Exception {
122        super.setUp();
123
124        mServiceContext = new BroadcastInterceptingContext(getContext());
125        mStatsDir = getContext().getFilesDir();
126        if (mStatsDir.exists()) {
127            IoUtils.deleteContents(mStatsDir);
128        }
129
130        mNetManager = createMock(INetworkManagementService.class);
131        mAlarmManager = createMock(IAlarmManager.class);
132        mTime = createMock(TrustedTime.class);
133        mSettings = createMock(NetworkStatsSettings.class);
134        mConnManager = createMock(IConnectivityManager.class);
135
136        mService = new NetworkStatsService(
137                mServiceContext, mNetManager, mAlarmManager, mTime, mStatsDir, mSettings);
138        mService.bindConnectivityManager(mConnManager);
139
140        mElapsedRealtime = 0L;
141
142        expectCurrentTime();
143        expectDefaultSettings();
144        expectNetworkStatsSummary(buildEmptyStats());
145        expectNetworkStatsUidDetail(buildEmptyStats());
146        expectSystemReady();
147
148        // catch INetworkManagementEventObserver during systemReady()
149        final Capture<INetworkManagementEventObserver> networkObserver = new Capture<
150                INetworkManagementEventObserver>();
151        mNetManager.registerObserver(capture(networkObserver));
152        expectLastCall().atLeastOnce();
153
154        replay();
155        mService.systemReady();
156        mSession = mService.openSession();
157        verifyAndReset();
158
159        mNetworkObserver = networkObserver.getValue();
160
161    }
162
163    @Override
164    public void tearDown() throws Exception {
165        for (File file : mStatsDir.listFiles()) {
166            file.delete();
167        }
168
169        mServiceContext = null;
170        mStatsDir = null;
171
172        mNetManager = null;
173        mAlarmManager = null;
174        mTime = null;
175        mSettings = null;
176        mConnManager = null;
177
178        mSession.close();
179        mService = null;
180
181        super.tearDown();
182    }
183
184    public void testNetworkStatsWifi() throws Exception {
185        // pretend that wifi network comes online; service should ask about full
186        // network state, and poll any existing interfaces before updating.
187        expectCurrentTime();
188        expectDefaultSettings();
189        expectNetworkState(buildWifiState());
190        expectNetworkStatsSummary(buildEmptyStats());
191        expectNetworkStatsUidDetail(buildEmptyStats());
192        expectNetworkStatsPoll();
193
194        replay();
195        mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
196
197        // verify service has empty history for wifi
198        assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
199        verifyAndReset();
200
201        // modify some number on wifi, and trigger poll event
202        incrementCurrentTime(HOUR_IN_MILLIS);
203        expectCurrentTime();
204        expectDefaultSettings();
205        expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
206                .addIfaceValues(TEST_IFACE, 1024L, 1L, 2048L, 2L));
207        expectNetworkStatsUidDetail(buildEmptyStats());
208        expectNetworkStatsPoll();
209
210        replay();
211        mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
212
213        // verify service recorded history
214        assertNetworkTotal(sTemplateWifi, 1024L, 1L, 2048L, 2L, 0);
215        verifyAndReset();
216
217        // and bump forward again, with counters going higher. this is
218        // important, since polling should correctly subtract last snapshot.
219        incrementCurrentTime(DAY_IN_MILLIS);
220        expectCurrentTime();
221        expectDefaultSettings();
222        expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
223                .addIfaceValues(TEST_IFACE, 4096L, 4L, 8192L, 8L));
224        expectNetworkStatsUidDetail(buildEmptyStats());
225        expectNetworkStatsPoll();
226
227        replay();
228        mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
229
230        // verify service recorded history
231        assertNetworkTotal(sTemplateWifi, 4096L, 4L, 8192L, 8L, 0);
232        verifyAndReset();
233
234    }
235
236    public void testStatsRebootPersist() throws Exception {
237        assertStatsFilesExist(false);
238
239        // pretend that wifi network comes online; service should ask about full
240        // network state, and poll any existing interfaces before updating.
241        expectCurrentTime();
242        expectDefaultSettings();
243        expectNetworkState(buildWifiState());
244        expectNetworkStatsSummary(buildEmptyStats());
245        expectNetworkStatsUidDetail(buildEmptyStats());
246        expectNetworkStatsPoll();
247
248        replay();
249        mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
250
251        // verify service has empty history for wifi
252        assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
253        verifyAndReset();
254
255        // modify some number on wifi, and trigger poll event
256        incrementCurrentTime(HOUR_IN_MILLIS);
257        expectCurrentTime();
258        expectDefaultSettings();
259        expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
260                .addIfaceValues(TEST_IFACE, 1024L, 8L, 2048L, 16L));
261        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 2)
262                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 512L, 4L, 256L, 2L, 0L)
263                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xFAAD, 256L, 2L, 128L, 1L, 0L)
264                .addValues(TEST_IFACE, UID_RED, SET_FOREGROUND, TAG_NONE, 512L, 4L, 256L, 2L, 0L)
265                .addValues(TEST_IFACE, UID_RED, SET_FOREGROUND, 0xFAAD, 256L, 2L, 128L, 1L, 0L)
266                .addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 128L, 1L, 128L, 1L, 0L));
267        expectNetworkStatsPoll();
268
269        mService.setUidForeground(UID_RED, false);
270        mService.incrementOperationCount(UID_RED, 0xFAAD, 4);
271        mService.setUidForeground(UID_RED, true);
272        mService.incrementOperationCount(UID_RED, 0xFAAD, 6);
273
274        replay();
275        mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
276
277        // verify service recorded history
278        assertNetworkTotal(sTemplateWifi, 1024L, 8L, 2048L, 16L, 0);
279        assertUidTotal(sTemplateWifi, UID_RED, 1024L, 8L, 512L, 4L, 10);
280        assertUidTotal(sTemplateWifi, UID_RED, SET_DEFAULT, 512L, 4L, 256L, 2L, 4);
281        assertUidTotal(sTemplateWifi, UID_RED, SET_FOREGROUND, 512L, 4L, 256L, 2L, 6);
282        assertUidTotal(sTemplateWifi, UID_BLUE, 128L, 1L, 128L, 1L, 0);
283        verifyAndReset();
284
285        // graceful shutdown system, which should trigger persist of stats, and
286        // clear any values in memory.
287        expectCurrentTime();
288        expectDefaultSettings();
289        replay();
290        mServiceContext.sendBroadcast(new Intent(Intent.ACTION_SHUTDOWN));
291        verifyAndReset();
292
293        assertStatsFilesExist(true);
294
295        // boot through serviceReady() again
296        expectCurrentTime();
297        expectDefaultSettings();
298        expectNetworkStatsSummary(buildEmptyStats());
299        expectNetworkStatsUidDetail(buildEmptyStats());
300        expectSystemReady();
301
302        // catch INetworkManagementEventObserver during systemReady()
303        final Capture<INetworkManagementEventObserver> networkObserver = new Capture<
304                INetworkManagementEventObserver>();
305        mNetManager.registerObserver(capture(networkObserver));
306        expectLastCall().atLeastOnce();
307
308        replay();
309        mService.systemReady();
310
311        mNetworkObserver = networkObserver.getValue();
312
313        // after systemReady(), we should have historical stats loaded again
314        assertNetworkTotal(sTemplateWifi, 1024L, 8L, 2048L, 16L, 0);
315        assertUidTotal(sTemplateWifi, UID_RED, 1024L, 8L, 512L, 4L, 10);
316        assertUidTotal(sTemplateWifi, UID_RED, SET_DEFAULT, 512L, 4L, 256L, 2L, 4);
317        assertUidTotal(sTemplateWifi, UID_RED, SET_FOREGROUND, 512L, 4L, 256L, 2L, 6);
318        assertUidTotal(sTemplateWifi, UID_BLUE, 128L, 1L, 128L, 1L, 0);
319        verifyAndReset();
320
321    }
322
323    // TODO: simulate reboot to test bucket resize
324    @Suppress
325    public void testStatsBucketResize() throws Exception {
326        NetworkStatsHistory history = null;
327
328        assertStatsFilesExist(false);
329
330        // pretend that wifi network comes online; service should ask about full
331        // network state, and poll any existing interfaces before updating.
332        expectCurrentTime();
333        expectSettings(0L, HOUR_IN_MILLIS, WEEK_IN_MILLIS);
334        expectNetworkState(buildWifiState());
335        expectNetworkStatsSummary(buildEmptyStats());
336        expectNetworkStatsUidDetail(buildEmptyStats());
337        expectNetworkStatsPoll();
338
339        replay();
340        mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
341        verifyAndReset();
342
343        // modify some number on wifi, and trigger poll event
344        incrementCurrentTime(2 * HOUR_IN_MILLIS);
345        expectCurrentTime();
346        expectSettings(0L, HOUR_IN_MILLIS, WEEK_IN_MILLIS);
347        expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
348                .addIfaceValues(TEST_IFACE, 512L, 4L, 512L, 4L));
349        expectNetworkStatsUidDetail(buildEmptyStats());
350        expectNetworkStatsPoll();
351
352        replay();
353        mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
354
355        // verify service recorded history
356        history = mSession.getHistoryForNetwork(sTemplateWifi, FIELD_ALL);
357        assertValues(history, Long.MIN_VALUE, Long.MAX_VALUE, 512L, 4L, 512L, 4L, 0);
358        assertEquals(HOUR_IN_MILLIS, history.getBucketDuration());
359        assertEquals(2, history.size());
360        verifyAndReset();
361
362        // now change bucket duration setting and trigger another poll with
363        // exact same values, which should resize existing buckets.
364        expectCurrentTime();
365        expectSettings(0L, 30 * MINUTE_IN_MILLIS, WEEK_IN_MILLIS);
366        expectNetworkStatsSummary(buildEmptyStats());
367        expectNetworkStatsUidDetail(buildEmptyStats());
368        expectNetworkStatsPoll();
369
370        replay();
371        mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
372
373        // verify identical stats, but spread across 4 buckets now
374        history = mSession.getHistoryForNetwork(sTemplateWifi, FIELD_ALL);
375        assertValues(history, Long.MIN_VALUE, Long.MAX_VALUE, 512L, 4L, 512L, 4L, 0);
376        assertEquals(30 * MINUTE_IN_MILLIS, history.getBucketDuration());
377        assertEquals(4, history.size());
378        verifyAndReset();
379
380    }
381
382    public void testUidStatsAcrossNetworks() throws Exception {
383        // pretend first mobile network comes online
384        expectCurrentTime();
385        expectDefaultSettings();
386        expectNetworkState(buildMobile3gState(IMSI_1));
387        expectNetworkStatsSummary(buildEmptyStats());
388        expectNetworkStatsUidDetail(buildEmptyStats());
389        expectNetworkStatsPoll();
390
391        replay();
392        mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
393        verifyAndReset();
394
395        // create some traffic on first network
396        incrementCurrentTime(HOUR_IN_MILLIS);
397        expectCurrentTime();
398        expectDefaultSettings();
399        expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
400                .addIfaceValues(TEST_IFACE, 2048L, 16L, 512L, 4L));
401        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 3)
402                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1536L, 12L, 512L, 4L, 0L)
403                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)
404                .addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 512L, 4L, 0L, 0L, 0L));
405        expectNetworkStatsPoll();
406
407        mService.incrementOperationCount(UID_RED, 0xF00D, 10);
408
409        replay();
410        mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
411
412        // verify service recorded history
413        assertNetworkTotal(sTemplateImsi1, 2048L, 16L, 512L, 4L, 0);
414        assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
415        assertUidTotal(sTemplateImsi1, UID_RED, 1536L, 12L, 512L, 4L, 10);
416        assertUidTotal(sTemplateImsi1, UID_BLUE, 512L, 4L, 0L, 0L, 0);
417        verifyAndReset();
418
419        // now switch networks; this also tests that we're okay with interfaces
420        // disappearing, to verify we don't count backwards.
421        incrementCurrentTime(HOUR_IN_MILLIS);
422        expectCurrentTime();
423        expectDefaultSettings();
424        expectNetworkState(buildMobile3gState(IMSI_2));
425        expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
426                .addIfaceValues(TEST_IFACE, 2048L, 16L, 512L, 4L));
427        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 3)
428                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1536L, 12L, 512L, 4L, 0L)
429                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)
430                .addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 512L, 4L, 0L, 0L, 0L));
431        expectNetworkStatsPoll();
432
433        replay();
434        mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
435        mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
436        verifyAndReset();
437
438        // create traffic on second network
439        incrementCurrentTime(HOUR_IN_MILLIS);
440        expectCurrentTime();
441        expectDefaultSettings();
442        expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
443                .addIfaceValues(TEST_IFACE, 2176L, 17L, 1536L, 12L));
444        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
445                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1536L, 12L, 512L, 4L, 0L)
446                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)
447                .addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 640L, 5L, 1024L, 8L, 0L)
448                .addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, 0xFAAD, 128L, 1L, 1024L, 8L, 0L));
449        expectNetworkStatsPoll();
450
451        mService.incrementOperationCount(UID_BLUE, 0xFAAD, 10);
452
453        replay();
454        mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
455
456        // verify original history still intact
457        assertNetworkTotal(sTemplateImsi1, 2048L, 16L, 512L, 4L, 0);
458        assertUidTotal(sTemplateImsi1, UID_RED, 1536L, 12L, 512L, 4L, 10);
459        assertUidTotal(sTemplateImsi1, UID_BLUE, 512L, 4L, 0L, 0L, 0);
460
461        // and verify new history also recorded under different template, which
462        // verifies that we didn't cross the streams.
463        assertNetworkTotal(sTemplateImsi2, 128L, 1L, 1024L, 8L, 0);
464        assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
465        assertUidTotal(sTemplateImsi2, UID_BLUE, 128L, 1L, 1024L, 8L, 10);
466        verifyAndReset();
467
468    }
469
470    public void testUidRemovedIsMoved() throws Exception {
471        // pretend that network comes online
472        expectCurrentTime();
473        expectDefaultSettings();
474        expectNetworkState(buildWifiState());
475        expectNetworkStatsSummary(buildEmptyStats());
476        expectNetworkStatsUidDetail(buildEmptyStats());
477        expectNetworkStatsPoll();
478
479        replay();
480        mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
481        verifyAndReset();
482
483        // create some traffic
484        incrementCurrentTime(HOUR_IN_MILLIS);
485        expectCurrentTime();
486        expectDefaultSettings();
487        expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
488                .addIfaceValues(TEST_IFACE, 4128L, 258L, 544L, 34L));
489        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
490                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L)
491                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xFAAD, 16L, 1L, 16L, 1L, 0L)
492                .addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 4096L, 258L, 512L, 32L, 0L)
493                .addValues(TEST_IFACE, UID_GREEN, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L));
494        expectNetworkStatsPoll();
495
496        mService.incrementOperationCount(UID_RED, 0xFAAD, 10);
497
498        replay();
499        mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
500
501        // verify service recorded history
502        assertNetworkTotal(sTemplateWifi, 4128L, 258L, 544L, 34L, 0);
503        assertUidTotal(sTemplateWifi, UID_RED, 16L, 1L, 16L, 1L, 10);
504        assertUidTotal(sTemplateWifi, UID_BLUE, 4096L, 258L, 512L, 32L, 0);
505        assertUidTotal(sTemplateWifi, UID_GREEN, 16L, 1L, 16L, 1L, 0);
506        verifyAndReset();
507
508        // now pretend two UIDs are uninstalled, which should migrate stats to
509        // special "removed" bucket.
510        expectCurrentTime();
511        expectDefaultSettings();
512        expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
513                .addIfaceValues(TEST_IFACE, 4128L, 258L, 544L, 34L));
514        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
515                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L)
516                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xFAAD, 16L, 1L, 16L, 1L, 0L)
517                .addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 4096L, 258L, 512L, 32L, 0L)
518                .addValues(TEST_IFACE, UID_GREEN, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L));
519        expectNetworkStatsPoll();
520
521        replay();
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        verifyAndReset();
536
537    }
538
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        expectNetworkStatsPoll();
547
548        replay();
549        mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
550        verifyAndReset();
551
552        // create some traffic
553        incrementCurrentTime(HOUR_IN_MILLIS);
554        expectCurrentTime();
555        expectDefaultSettings();
556        expectNetworkStatsSummary(buildEmptyStats());
557        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
558                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 0L)
559                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L));
560        expectNetworkStatsPoll();
561
562        mService.incrementOperationCount(UID_RED, 0xF00D, 5);
563
564        replay();
565        mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
566
567        // verify service recorded history
568        assertUidTotal(sTemplateImsi1, UID_RED, 1024L, 8L, 1024L, 8L, 5);
569        verifyAndReset();
570
571        // now switch over to 4g network
572        incrementCurrentTime(HOUR_IN_MILLIS);
573        expectCurrentTime();
574        expectDefaultSettings();
575        expectNetworkState(buildMobile4gState(TEST_IFACE2));
576        expectNetworkStatsSummary(buildEmptyStats());
577        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
578                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 0L)
579                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L));
580        expectNetworkStatsPoll();
581
582        replay();
583        mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
584        mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
585        verifyAndReset();
586
587        // create traffic on second network
588        incrementCurrentTime(HOUR_IN_MILLIS);
589        expectCurrentTime();
590        expectDefaultSettings();
591        expectNetworkStatsSummary(buildEmptyStats());
592        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
593                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 0L)
594                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)
595                .addValues(TEST_IFACE2, UID_RED, SET_DEFAULT, TAG_NONE, 512L, 4L, 256L, 2L, 0L)
596                .addValues(TEST_IFACE2, UID_RED, SET_DEFAULT, 0xFAAD, 512L, 4L, 256L, 2L, 0L));
597        expectNetworkStatsPoll();
598
599        mService.incrementOperationCount(UID_RED, 0xFAAD, 5);
600
601        replay();
602        mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
603
604        // verify that ALL_MOBILE template combines both
605        assertUidTotal(sTemplateImsi1, UID_RED, 1536L, 12L, 1280L, 10L, 10);
606
607        verifyAndReset();
608    }
609
610    public void testSummaryForAllUid() throws Exception {
611        // pretend that network comes online
612        expectCurrentTime();
613        expectDefaultSettings();
614        expectNetworkState(buildWifiState());
615        expectNetworkStatsSummary(buildEmptyStats());
616        expectNetworkStatsUidDetail(buildEmptyStats());
617        expectNetworkStatsPoll();
618
619        replay();
620        mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
621        verifyAndReset();
622
623        // create some traffic for two apps
624        incrementCurrentTime(HOUR_IN_MILLIS);
625        expectCurrentTime();
626        expectDefaultSettings();
627        expectNetworkStatsSummary(buildEmptyStats());
628        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
629                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 50L, 5L, 50L, 5L, 0L)
630                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 10L, 1L, 10L, 1L, 0L)
631                .addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 1024L, 8L, 512L, 4L, 0L));
632        expectNetworkStatsPoll();
633
634        mService.incrementOperationCount(UID_RED, 0xF00D, 1);
635
636        replay();
637        mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
638
639        // verify service recorded history
640        assertUidTotal(sTemplateWifi, UID_RED, 50L, 5L, 50L, 5L, 1);
641        assertUidTotal(sTemplateWifi, UID_BLUE, 1024L, 8L, 512L, 4L, 0);
642        verifyAndReset();
643
644        // now create more traffic in next hour, but only for one app
645        incrementCurrentTime(HOUR_IN_MILLIS);
646        expectCurrentTime();
647        expectDefaultSettings();
648        expectNetworkStatsSummary(buildEmptyStats());
649        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
650                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 50L, 5L, 50L, 5L, 0L)
651                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 10L, 1L, 10L, 1L, 0L)
652                .addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 2048L, 16L, 1024L, 8L, 0L));
653        expectNetworkStatsPoll();
654
655        replay();
656        mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
657
658        // first verify entire history present
659        NetworkStats stats = mSession.getSummaryForAllUid(
660                sTemplateWifi, Long.MIN_VALUE, Long.MAX_VALUE, true);
661        assertEquals(3, stats.size());
662        assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, TAG_NONE, 50L, 5L, 50L, 5L, 1);
663        assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, 0xF00D, 10L, 1L, 10L, 1L, 1);
664        assertValues(stats, IFACE_ALL, UID_BLUE, SET_DEFAULT, TAG_NONE, 2048L, 16L, 1024L, 8L, 0);
665
666        // now verify that recent history only contains one uid
667        final long currentTime = currentTimeMillis();
668        stats = mSession.getSummaryForAllUid(
669                sTemplateWifi, currentTime - HOUR_IN_MILLIS, currentTime, true);
670        assertEquals(1, stats.size());
671        assertValues(stats, IFACE_ALL, UID_BLUE, SET_DEFAULT, TAG_NONE, 1024L, 8L, 512L, 4L, 0);
672
673        verifyAndReset();
674    }
675
676    public void testForegroundBackground() throws Exception {
677        // pretend that network comes online
678        expectCurrentTime();
679        expectDefaultSettings();
680        expectNetworkState(buildWifiState());
681        expectNetworkStatsSummary(buildEmptyStats());
682        expectNetworkStatsUidDetail(buildEmptyStats());
683        expectNetworkStatsPoll();
684
685        replay();
686        mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
687        verifyAndReset();
688
689        // create some initial traffic
690        incrementCurrentTime(HOUR_IN_MILLIS);
691        expectCurrentTime();
692        expectDefaultSettings();
693        expectNetworkStatsSummary(buildEmptyStats());
694        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
695                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L)
696                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 64L, 1L, 64L, 1L, 0L));
697        expectNetworkStatsPoll();
698
699        mService.incrementOperationCount(UID_RED, 0xF00D, 1);
700
701        replay();
702        mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
703
704        // verify service recorded history
705        assertUidTotal(sTemplateWifi, UID_RED, 128L, 2L, 128L, 2L, 1);
706        verifyAndReset();
707
708        // now switch to foreground
709        incrementCurrentTime(HOUR_IN_MILLIS);
710        expectCurrentTime();
711        expectDefaultSettings();
712        expectNetworkStatsSummary(buildEmptyStats());
713        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
714                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L)
715                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 64L, 1L, 64L, 1L, 0L)
716                .addValues(TEST_IFACE, UID_RED, SET_FOREGROUND, TAG_NONE, 32L, 2L, 32L, 2L, 0L)
717                .addValues(TEST_IFACE, UID_RED, SET_FOREGROUND, 0xFAAD, 1L, 1L, 1L, 1L, 0L));
718        expectNetworkStatsPoll();
719
720        mService.setUidForeground(UID_RED, true);
721        mService.incrementOperationCount(UID_RED, 0xFAAD, 1);
722
723        replay();
724        mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
725
726        // test that we combined correctly
727        assertUidTotal(sTemplateWifi, UID_RED, 160L, 4L, 160L, 4L, 2);
728
729        // verify entire history present
730        final NetworkStats stats = mSession.getSummaryForAllUid(
731                sTemplateWifi, Long.MIN_VALUE, Long.MAX_VALUE, true);
732        assertEquals(4, stats.size());
733        assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 1);
734        assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, 0xF00D, 64L, 1L, 64L, 1L, 1);
735        assertValues(stats, IFACE_ALL, UID_RED, SET_FOREGROUND, TAG_NONE, 32L, 2L, 32L, 2L, 1);
736        assertValues(stats, IFACE_ALL, UID_RED, SET_FOREGROUND, 0xFAAD, 1L, 1L, 1L, 1L, 1);
737
738        verifyAndReset();
739    }
740
741    public void testTethering() throws Exception {
742        // pretend first mobile network comes online
743        expectCurrentTime();
744        expectDefaultSettings();
745        expectNetworkState(buildMobile3gState(IMSI_1));
746        expectNetworkStatsSummary(buildEmptyStats());
747        expectNetworkStatsUidDetail(buildEmptyStats());
748        expectNetworkStatsPoll();
749
750        replay();
751        mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
752        verifyAndReset();
753
754        // create some tethering traffic
755        incrementCurrentTime(HOUR_IN_MILLIS);
756        expectCurrentTime();
757        expectDefaultSettings();
758        expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
759                .addIfaceValues(TEST_IFACE, 2048L, 16L, 512L, 4L));
760
761        final NetworkStats uidStats = new NetworkStats(getElapsedRealtime(), 1)
762                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L);
763        final String[] tetherIfacePairs = new String[] { TEST_IFACE, "wlan0" };
764        final NetworkStats tetherStats = new NetworkStats(getElapsedRealtime(), 1)
765                .addValues(TEST_IFACE, UID_TETHERING, SET_DEFAULT, TAG_NONE, 1920L, 14L, 384L, 2L, 0L);
766
767        expectNetworkStatsUidDetail(uidStats, tetherIfacePairs, tetherStats);
768        expectNetworkStatsPoll();
769
770        replay();
771        mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
772
773        // verify service recorded history
774        assertNetworkTotal(sTemplateImsi1, 2048L, 16L, 512L, 4L, 0);
775        assertUidTotal(sTemplateImsi1, UID_RED, 128L, 2L, 128L, 2L, 0);
776        assertUidTotal(sTemplateImsi1, UID_TETHERING, 1920L, 14L, 384L, 2L, 0);
777        verifyAndReset();
778
779    }
780
781    private void assertNetworkTotal(NetworkTemplate template, long rxBytes, long rxPackets,
782            long txBytes, long txPackets, int operations) throws Exception {
783        final NetworkStatsHistory history = mSession.getHistoryForNetwork(template, FIELD_ALL);
784        assertValues(history, Long.MIN_VALUE, Long.MAX_VALUE, rxBytes, rxPackets, txBytes,
785                txPackets, operations);
786    }
787
788    private void assertUidTotal(NetworkTemplate template, int uid, long rxBytes, long rxPackets,
789            long txBytes, long txPackets, int operations) throws Exception {
790        assertUidTotal(template, uid, SET_ALL, rxBytes, rxPackets, txBytes, txPackets, operations);
791    }
792
793    private void assertUidTotal(NetworkTemplate template, int uid, int set, long rxBytes,
794            long rxPackets, long txBytes, long txPackets, int operations) throws Exception {
795        final NetworkStatsHistory history = mSession.getHistoryForUid(
796                template, uid, set, TAG_NONE, FIELD_ALL);
797        assertValues(history, Long.MIN_VALUE, Long.MAX_VALUE, rxBytes, rxPackets, txBytes,
798                txPackets, operations);
799    }
800
801    private void expectSystemReady() throws Exception {
802        mAlarmManager.remove(isA(PendingIntent.class));
803        expectLastCall().anyTimes();
804
805        mAlarmManager.setInexactRepeating(
806                eq(AlarmManager.ELAPSED_REALTIME), anyLong(), anyLong(), isA(PendingIntent.class));
807        expectLastCall().atLeastOnce();
808
809        mNetManager.setGlobalAlert(anyLong());
810        expectLastCall().atLeastOnce();
811
812        expect(mNetManager.isBandwidthControlEnabled()).andReturn(true).atLeastOnce();
813    }
814
815    private void expectNetworkState(NetworkState... state) throws Exception {
816        expect(mConnManager.getAllNetworkState()).andReturn(state).atLeastOnce();
817
818        final LinkProperties linkProp = state.length > 0 ? state[0].linkProperties : null;
819        expect(mConnManager.getActiveLinkProperties()).andReturn(linkProp).atLeastOnce();
820    }
821
822    private void expectNetworkStatsSummary(NetworkStats summary) throws Exception {
823        expect(mNetManager.getNetworkStatsSummaryDev()).andReturn(summary).atLeastOnce();
824        expect(mNetManager.getNetworkStatsSummaryXt()).andReturn(summary).atLeastOnce();
825    }
826
827    private void expectNetworkStatsUidDetail(NetworkStats detail) throws Exception {
828        expectNetworkStatsUidDetail(detail, new String[0], new NetworkStats(0L, 0));
829    }
830
831    private void expectNetworkStatsUidDetail(
832            NetworkStats detail, String[] tetherIfacePairs, NetworkStats tetherStats)
833            throws Exception {
834        expect(mNetManager.getNetworkStatsUidDetail(eq(UID_ALL))).andReturn(detail).atLeastOnce();
835
836        // also include tethering details, since they are folded into UID
837        expect(mConnManager.getTetheredIfacePairs()).andReturn(tetherIfacePairs).atLeastOnce();
838        expect(mNetManager.getNetworkStatsTethering(aryEq(tetherIfacePairs)))
839                .andReturn(tetherStats).atLeastOnce();
840    }
841
842    private void expectDefaultSettings() throws Exception {
843        expectSettings(0L, HOUR_IN_MILLIS, WEEK_IN_MILLIS);
844    }
845
846    private void expectSettings(long persistBytes, long bucketDuration, long deleteAge)
847            throws Exception {
848        expect(mSettings.getPollInterval()).andReturn(HOUR_IN_MILLIS).anyTimes();
849        expect(mSettings.getTimeCacheMaxAge()).andReturn(DAY_IN_MILLIS).anyTimes();
850        expect(mSettings.getGlobalAlertBytes()).andReturn(MB_IN_BYTES).anyTimes();
851        expect(mSettings.getSampleEnabled()).andReturn(true).anyTimes();
852
853        final Config config = new Config(bucketDuration, persistBytes, deleteAge, deleteAge);
854        expect(mSettings.getDevConfig()).andReturn(config).anyTimes();
855        expect(mSettings.getXtConfig()).andReturn(config).anyTimes();
856        expect(mSettings.getUidConfig()).andReturn(config).anyTimes();
857        expect(mSettings.getUidTagConfig()).andReturn(config).anyTimes();
858    }
859
860    private void expectCurrentTime() throws Exception {
861        expect(mTime.forceRefresh()).andReturn(false).anyTimes();
862        expect(mTime.hasCache()).andReturn(true).anyTimes();
863        expect(mTime.currentTimeMillis()).andReturn(currentTimeMillis()).anyTimes();
864        expect(mTime.getCacheAge()).andReturn(0L).anyTimes();
865        expect(mTime.getCacheCertainty()).andReturn(0L).anyTimes();
866    }
867
868    private void expectNetworkStatsPoll() throws Exception {
869        mNetManager.setGlobalAlert(anyLong());
870        expectLastCall().anyTimes();
871    }
872
873    private void assertStatsFilesExist(boolean exist) {
874        final File basePath = new File(mStatsDir, "netstats");
875        if (exist) {
876            assertTrue(basePath.list().length > 0);
877        } else {
878            assertTrue(basePath.list().length == 0);
879        }
880    }
881
882    private static void assertValues(NetworkStats stats, String iface, int uid, int set,
883            int tag, long rxBytes, long rxPackets, long txBytes, long txPackets, int operations) {
884        final int i = stats.findIndex(iface, uid, set, tag);
885        final NetworkStats.Entry entry = stats.getValues(i, null);
886        assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes);
887        assertEquals("unexpected rxPackets", rxPackets, entry.rxPackets);
888        assertEquals("unexpected txBytes", txBytes, entry.txBytes);
889        assertEquals("unexpected txPackets", txPackets, entry.txPackets);
890        assertEquals("unexpected operations", operations, entry.operations);
891    }
892
893    private static void assertValues(NetworkStatsHistory stats, long start, long end, long rxBytes,
894            long rxPackets, long txBytes, long txPackets, int operations) {
895        final NetworkStatsHistory.Entry entry = stats.getValues(start, end, null);
896        assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes);
897        assertEquals("unexpected rxPackets", rxPackets, entry.rxPackets);
898        assertEquals("unexpected txBytes", txBytes, entry.txBytes);
899        assertEquals("unexpected txPackets", txPackets, entry.txPackets);
900        assertEquals("unexpected operations", operations, entry.operations);
901    }
902
903    private static NetworkState buildWifiState() {
904        final NetworkInfo info = new NetworkInfo(TYPE_WIFI, 0, null, null);
905        info.setDetailedState(DetailedState.CONNECTED, null, null);
906        final LinkProperties prop = new LinkProperties();
907        prop.setInterfaceName(TEST_IFACE);
908        return new NetworkState(info, prop, null);
909    }
910
911    private static NetworkState buildMobile3gState(String subscriberId) {
912        final NetworkInfo info = new NetworkInfo(
913                TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UMTS, null, null);
914        info.setDetailedState(DetailedState.CONNECTED, null, null);
915        final LinkProperties prop = new LinkProperties();
916        prop.setInterfaceName(TEST_IFACE);
917        return new NetworkState(info, prop, null, subscriberId, null);
918    }
919
920    private static NetworkState buildMobile4gState(String iface) {
921        final NetworkInfo info = new NetworkInfo(TYPE_WIMAX, 0, null, null);
922        info.setDetailedState(DetailedState.CONNECTED, null, null);
923        final LinkProperties prop = new LinkProperties();
924        prop.setInterfaceName(iface);
925        return new NetworkState(info, prop, null);
926    }
927
928    private NetworkStats buildEmptyStats() {
929        return new NetworkStats(getElapsedRealtime(), 0);
930    }
931
932    private long getElapsedRealtime() {
933        return mElapsedRealtime;
934    }
935
936    private long startTimeMillis() {
937        return TEST_START;
938    }
939
940    private long currentTimeMillis() {
941        return startTimeMillis() + mElapsedRealtime;
942    }
943
944    private void incrementCurrentTime(long duration) {
945        mElapsedRealtime += duration;
946    }
947
948    private void replay() {
949        EasyMock.replay(mNetManager, mAlarmManager, mTime, mSettings, mConnManager);
950    }
951
952    private void verifyAndReset() {
953        EasyMock.verify(mNetManager, mAlarmManager, mTime, mSettings, mConnManager);
954        EasyMock.reset(mNetManager, mAlarmManager, mTime, mSettings, mConnManager);
955    }
956}
957