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