• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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 
17 package android.app.usage;
18 
19 import static junit.framework.Assert.assertEquals;
20 import static junit.framework.Assert.assertFalse;
21 import static junit.framework.Assert.assertTrue;
22 
23 import static org.mockito.ArgumentMatchers.any;
24 import static org.mockito.ArgumentMatchers.anyInt;
25 import static org.mockito.ArgumentMatchers.anyLong;
26 import static org.mockito.ArgumentMatchers.anyString;
27 import static org.mockito.ArgumentMatchers.argThat;
28 import static org.mockito.ArgumentMatchers.eq;
29 import static org.mockito.Mockito.atLeastOnce;
30 import static org.mockito.Mockito.times;
31 import static org.mockito.Mockito.verify;
32 import static org.mockito.Mockito.when;
33 
34 import android.net.ConnectivityManager;
35 import android.net.INetworkStatsService;
36 import android.net.INetworkStatsSession;
37 import android.net.NetworkStats.Entry;
38 import android.net.NetworkStatsHistory;
39 import android.net.NetworkTemplate;
40 import android.os.RemoteException;
41 import android.support.test.InstrumentationRegistry;
42 import android.support.test.filters.SmallTest;
43 import android.support.test.runner.AndroidJUnit4;
44 
45 import org.junit.Before;
46 import org.junit.Test;
47 import org.junit.runner.RunWith;
48 import org.mockito.Mock;
49 import org.mockito.MockitoAnnotations;
50 import org.mockito.invocation.InvocationOnMock;
51 
52 @RunWith(AndroidJUnit4.class)
53 @SmallTest
54 public class NetworkStatsManagerTest {
55 
56     private @Mock INetworkStatsService mService;
57     private @Mock INetworkStatsSession mStatsSession;
58 
59     private NetworkStatsManager mManager;
60 
61     // TODO: change to NetworkTemplate.MATCH_MOBILE once internal constant rename is merged to aosp.
62     private static final int MATCH_MOBILE_ALL = 1;
63 
64     @Before
setUp()65     public void setUp() {
66         MockitoAnnotations.initMocks(this);
67         mManager = new NetworkStatsManager(InstrumentationRegistry.getContext(), mService);
68     }
69 
70     @Test
testQueryDetails()71     public void testQueryDetails() throws RemoteException {
72         final String subscriberId = "subid";
73         final long startTime = 1;
74         final long endTime = 100;
75         final int uid1 = 10001;
76         final int uid2 = 10002;
77         final int uid3 = 10003;
78 
79         Entry uid1Entry1 = new Entry("if1", uid1,
80                 android.net.NetworkStats.SET_DEFAULT, android.net.NetworkStats.TAG_NONE,
81                 100, 10, 200, 20, 0);
82 
83         Entry uid1Entry2 = new Entry(
84                 "if2", uid1,
85                 android.net.NetworkStats.SET_DEFAULT, android.net.NetworkStats.TAG_NONE,
86                 100, 10, 200, 20, 0);
87 
88         Entry uid2Entry1 = new Entry("if1", uid2,
89                 android.net.NetworkStats.SET_DEFAULT, android.net.NetworkStats.TAG_NONE,
90                 150, 10, 250, 20, 0);
91 
92         Entry uid2Entry2 = new Entry(
93                 "if2", uid2,
94                 android.net.NetworkStats.SET_DEFAULT, android.net.NetworkStats.TAG_NONE,
95                 150, 10, 250, 20, 0);
96 
97         NetworkStatsHistory history1 = new NetworkStatsHistory(10, 2);
98         history1.recordData(10, 20, uid1Entry1);
99         history1.recordData(20, 30, uid1Entry2);
100 
101         NetworkStatsHistory history2 = new NetworkStatsHistory(10, 2);
102         history1.recordData(30, 40, uid2Entry1);
103         history1.recordData(35, 45, uid2Entry2);
104 
105 
106         when(mService.openSessionForUsageStats(anyInt(), anyString())).thenReturn(mStatsSession);
107         when(mStatsSession.getRelevantUids()).thenReturn(new int[] { uid1, uid2, uid3 });
108 
109         when(mStatsSession.getHistoryIntervalForUid(any(NetworkTemplate.class),
110                 eq(uid1), eq(android.net.NetworkStats.SET_ALL),
111                 eq(android.net.NetworkStats.TAG_NONE),
112                 eq(NetworkStatsHistory.FIELD_ALL), eq(startTime), eq(endTime)))
113                 .then((InvocationOnMock inv) -> {
114                     NetworkTemplate template = inv.getArgument(0);
115                     assertEquals(MATCH_MOBILE_ALL, template.getMatchRule());
116                     assertEquals(subscriberId, template.getSubscriberId());
117                     return history1;
118                 });
119 
120         when(mStatsSession.getHistoryIntervalForUid(any(NetworkTemplate.class),
121                 eq(uid2), eq(android.net.NetworkStats.SET_ALL),
122                 eq(android.net.NetworkStats.TAG_NONE),
123                 eq(NetworkStatsHistory.FIELD_ALL), eq(startTime), eq(endTime)))
124                 .then((InvocationOnMock inv) -> {
125                     NetworkTemplate template = inv.getArgument(0);
126                     assertEquals(MATCH_MOBILE_ALL, template.getMatchRule());
127                     assertEquals(subscriberId, template.getSubscriberId());
128                     return history2;
129                 });
130 
131 
132         NetworkStats stats = mManager.queryDetails(
133                 ConnectivityManager.TYPE_MOBILE, subscriberId, startTime, endTime);
134 
135         NetworkStats.Bucket bucket = new NetworkStats.Bucket();
136 
137         // First 2 buckets exactly match entry timings
138         assertTrue(stats.getNextBucket(bucket));
139         assertEquals(10, bucket.getStartTimeStamp());
140         assertEquals(20, bucket.getEndTimeStamp());
141         assertBucketMatches(uid1Entry1, bucket);
142 
143         assertTrue(stats.getNextBucket(bucket));
144         assertEquals(20, bucket.getStartTimeStamp());
145         assertEquals(30, bucket.getEndTimeStamp());
146         assertBucketMatches(uid1Entry2, bucket);
147 
148         // 30 -> 40: contains uid2Entry1 and half of uid2Entry2
149         assertTrue(stats.getNextBucket(bucket));
150         assertEquals(30, bucket.getStartTimeStamp());
151         assertEquals(40, bucket.getEndTimeStamp());
152         assertEquals(225, bucket.getRxBytes());
153         assertEquals(15, bucket.getRxPackets());
154         assertEquals(375, bucket.getTxBytes());
155         assertEquals(30, bucket.getTxPackets());
156 
157         // 40 -> 50: contains half of uid2Entry2
158         assertTrue(stats.getNextBucket(bucket));
159         assertEquals(40, bucket.getStartTimeStamp());
160         assertEquals(50, bucket.getEndTimeStamp());
161         assertEquals(75, bucket.getRxBytes());
162         assertEquals(5, bucket.getRxPackets());
163         assertEquals(125, bucket.getTxBytes());
164         assertEquals(10, bucket.getTxPackets());
165 
166         assertFalse(stats.hasNextBucket());
167     }
168 
169     @Test
testQueryDetails_NoSubscriberId()170     public void testQueryDetails_NoSubscriberId() throws RemoteException {
171         final long startTime = 1;
172         final long endTime = 100;
173         final int uid1 = 10001;
174         final int uid2 = 10002;
175 
176         when(mService.openSessionForUsageStats(anyInt(), anyString())).thenReturn(mStatsSession);
177         when(mStatsSession.getRelevantUids()).thenReturn(new int[] { uid1, uid2 });
178 
179         NetworkStats stats = mManager.queryDetails(
180                 ConnectivityManager.TYPE_MOBILE, null, startTime, endTime);
181 
182         when(mStatsSession.getHistoryIntervalForUid(any(NetworkTemplate.class),
183                 anyInt(), anyInt(), anyInt(), anyInt(), anyLong(), anyLong()))
184                 .thenReturn(new NetworkStatsHistory(10, 0));
185 
186         verify(mStatsSession, times(1)).getHistoryIntervalForUid(
187                 argThat((NetworkTemplate t) ->
188                         // No subscriberId: MATCH_MOBILE_WILDCARD template
189                         t.getMatchRule() == NetworkTemplate.MATCH_MOBILE_WILDCARD),
190                 eq(uid1), eq(android.net.NetworkStats.SET_ALL),
191                 eq(android.net.NetworkStats.TAG_NONE),
192                 eq(NetworkStatsHistory.FIELD_ALL), eq(startTime), eq(endTime));
193 
194         verify(mStatsSession, times(1)).getHistoryIntervalForUid(
195                 argThat((NetworkTemplate t) ->
196                         // No subscriberId: MATCH_MOBILE_WILDCARD template
197                         t.getMatchRule() == NetworkTemplate.MATCH_MOBILE_WILDCARD),
198                 eq(uid2), eq(android.net.NetworkStats.SET_ALL),
199                 eq(android.net.NetworkStats.TAG_NONE),
200                 eq(NetworkStatsHistory.FIELD_ALL), eq(startTime), eq(endTime));
201 
202         assertFalse(stats.hasNextBucket());
203     }
204 
assertBucketMatches(Entry expected, NetworkStats.Bucket actual)205     private void assertBucketMatches(Entry expected,
206             NetworkStats.Bucket actual) {
207         assertEquals(expected.uid, actual.getUid());
208         assertEquals(expected.rxBytes, actual.getRxBytes());
209         assertEquals(expected.rxPackets, actual.getRxPackets());
210         assertEquals(expected.txBytes, actual.getTxBytes());
211         assertEquals(expected.txPackets, actual.getTxPackets());
212     }
213 }
214