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