Loading core/java/android/app/usage/NetworkStats.java +2 −4 Original line number Diff line number Diff line Loading @@ -24,7 +24,6 @@ import android.net.NetworkStatsHistory; import android.net.NetworkTemplate; import android.net.TrafficStats; import android.os.RemoteException; import android.os.ServiceManager; import android.util.IntArray; import android.util.Log; Loading Loading @@ -98,9 +97,8 @@ public final class NetworkStats implements AutoCloseable { /** @hide */ NetworkStats(Context context, NetworkTemplate template, int flags, long startTimestamp, long endTimestamp) throws RemoteException, SecurityException { final INetworkStatsService statsService = INetworkStatsService.Stub.asInterface( ServiceManager.getService(Context.NETWORK_STATS_SERVICE)); long endTimestamp, INetworkStatsService statsService) throws RemoteException, SecurityException { // Open network stats session mSession = statsService.openSessionForUsageStats(flags, context.getOpPackageName()); mCloseGuard.open("close"); Loading core/java/android/app/usage/NetworkStatsManager.java +25 −15 Original line number Diff line number Diff line Loading @@ -37,6 +37,8 @@ import android.os.ServiceManager; import android.os.ServiceManager.ServiceNotFoundException; import android.util.Log; import com.android.internal.annotations.VisibleForTesting; /** * Provides access to network usage history and statistics. Usage data is collected in * discrete bins of time called 'Buckets'. See {@link NetworkStats.Bucket} for details. Loading Loading @@ -107,9 +109,15 @@ public class NetworkStatsManager { * {@hide} */ public NetworkStatsManager(Context context) throws ServiceNotFoundException { this(context, INetworkStatsService.Stub.asInterface( ServiceManager.getServiceOrThrow(Context.NETWORK_STATS_SERVICE))); } /** @hide */ @VisibleForTesting public NetworkStatsManager(Context context, INetworkStatsService service) { mContext = context; mService = INetworkStatsService.Stub.asInterface( ServiceManager.getServiceOrThrow(Context.NETWORK_STATS_SERVICE)); mService = service; setPollOnOpen(true); } Loading @@ -135,7 +143,8 @@ public class NetworkStatsManager { public Bucket querySummaryForDevice(NetworkTemplate template, long startTime, long endTime) throws SecurityException, RemoteException { Bucket bucket = null; NetworkStats stats = new NetworkStats(mContext, template, mFlags, startTime, endTime); NetworkStats stats = new NetworkStats(mContext, template, mFlags, startTime, endTime, mService); bucket = stats.getDeviceSummaryForNetwork(); stats.close(); Loading Loading @@ -208,7 +217,7 @@ public class NetworkStatsManager { } NetworkStats stats; stats = new NetworkStats(mContext, template, mFlags, startTime, endTime); stats = new NetworkStats(mContext, template, mFlags, startTime, endTime, mService); stats.startSummaryEnumeration(); stats.close(); Loading Loading @@ -245,7 +254,7 @@ public class NetworkStatsManager { } NetworkStats result; result = new NetworkStats(mContext, template, mFlags, startTime, endTime); result = new NetworkStats(mContext, template, mFlags, startTime, endTime, mService); result.startSummaryEnumeration(); return result; Loading Loading @@ -295,7 +304,7 @@ public class NetworkStatsManager { NetworkStats result; try { result = new NetworkStats(mContext, template, mFlags, startTime, endTime); result = new NetworkStats(mContext, template, mFlags, startTime, endTime, mService); result.startHistoryEnumeration(uid, tag); } catch (RemoteException e) { Log.e(TAG, "Error while querying stats for uid=" + uid + " tag=" + tag, e); Loading Loading @@ -341,7 +350,7 @@ public class NetworkStatsManager { } NetworkStats result; result = new NetworkStats(mContext, template, mFlags, startTime, endTime); result = new NetworkStats(mContext, template, mFlags, startTime, endTime, mService); result.startUserUidEnumeration(); return result; } Loading Loading @@ -451,20 +460,21 @@ public class NetworkStatsManager { } private static NetworkTemplate createTemplate(int networkType, String subscriberId) { NetworkTemplate template = null; final NetworkTemplate template; switch (networkType) { case ConnectivityManager.TYPE_MOBILE: { template = NetworkTemplate.buildTemplateMobileAll(subscriberId); } break; case ConnectivityManager.TYPE_WIFI: { case ConnectivityManager.TYPE_MOBILE: template = subscriberId == null ? NetworkTemplate.buildTemplateMobileWildcard() : NetworkTemplate.buildTemplateMobileAll(subscriberId); break; case ConnectivityManager.TYPE_WIFI: template = NetworkTemplate.buildTemplateWifiWildcard(); } break; default: { break; default: throw new IllegalArgumentException("Cannot create template for network type " + networkType + ", subscriberId '" + NetworkIdentity.scrubSubscriberId(subscriberId) + "'."); } } return template; } Loading tests/net/java/android/app/usage/NetworkStatsManagerTest.java 0 → 100644 +213 −0 Original line number Diff line number Diff line /* * Copyright (C) 2018 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.app.usage; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertFalse; import static junit.framework.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.net.ConnectivityManager; import android.net.INetworkStatsService; import android.net.INetworkStatsSession; import android.net.NetworkStats.Entry; import android.net.NetworkStatsHistory; import android.net.NetworkTemplate; import android.os.RemoteException; import android.support.test.InstrumentationRegistry; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.mockito.invocation.InvocationOnMock; @RunWith(AndroidJUnit4.class) @SmallTest public class NetworkStatsManagerTest { private @Mock INetworkStatsService mService; private @Mock INetworkStatsSession mStatsSession; private NetworkStatsManager mManager; // TODO: change to NetworkTemplate.MATCH_MOBILE once internal constant rename is merged to aosp. private static final int MATCH_MOBILE_ALL = 1; @Before public void setUp() { MockitoAnnotations.initMocks(this); mManager = new NetworkStatsManager(InstrumentationRegistry.getContext(), mService); } @Test public void testQueryDetails() throws RemoteException { final String subscriberId = "subid"; final long startTime = 1; final long endTime = 100; final int uid1 = 10001; final int uid2 = 10002; final int uid3 = 10003; Entry uid1Entry1 = new Entry("if1", uid1, android.net.NetworkStats.SET_DEFAULT, android.net.NetworkStats.TAG_NONE, 100, 10, 200, 20, 0); Entry uid1Entry2 = new Entry( "if2", uid1, android.net.NetworkStats.SET_DEFAULT, android.net.NetworkStats.TAG_NONE, 100, 10, 200, 20, 0); Entry uid2Entry1 = new Entry("if1", uid2, android.net.NetworkStats.SET_DEFAULT, android.net.NetworkStats.TAG_NONE, 150, 10, 250, 20, 0); Entry uid2Entry2 = new Entry( "if2", uid2, android.net.NetworkStats.SET_DEFAULT, android.net.NetworkStats.TAG_NONE, 150, 10, 250, 20, 0); NetworkStatsHistory history1 = new NetworkStatsHistory(10, 2); history1.recordData(10, 20, uid1Entry1); history1.recordData(20, 30, uid1Entry2); NetworkStatsHistory history2 = new NetworkStatsHistory(10, 2); history1.recordData(30, 40, uid2Entry1); history1.recordData(35, 45, uid2Entry2); when(mService.openSessionForUsageStats(anyInt(), anyString())).thenReturn(mStatsSession); when(mStatsSession.getRelevantUids()).thenReturn(new int[] { uid1, uid2, uid3 }); when(mStatsSession.getHistoryIntervalForUid(any(NetworkTemplate.class), eq(uid1), eq(android.net.NetworkStats.SET_ALL), eq(android.net.NetworkStats.TAG_NONE), eq(NetworkStatsHistory.FIELD_ALL), eq(startTime), eq(endTime))) .then((InvocationOnMock inv) -> { NetworkTemplate template = inv.getArgument(0); assertEquals(MATCH_MOBILE_ALL, template.getMatchRule()); assertEquals(subscriberId, template.getSubscriberId()); return history1; }); when(mStatsSession.getHistoryIntervalForUid(any(NetworkTemplate.class), eq(uid2), eq(android.net.NetworkStats.SET_ALL), eq(android.net.NetworkStats.TAG_NONE), eq(NetworkStatsHistory.FIELD_ALL), eq(startTime), eq(endTime))) .then((InvocationOnMock inv) -> { NetworkTemplate template = inv.getArgument(0); assertEquals(MATCH_MOBILE_ALL, template.getMatchRule()); assertEquals(subscriberId, template.getSubscriberId()); return history2; }); NetworkStats stats = mManager.queryDetails( ConnectivityManager.TYPE_MOBILE, subscriberId, startTime, endTime); NetworkStats.Bucket bucket = new NetworkStats.Bucket(); // First 2 buckets exactly match entry timings assertTrue(stats.getNextBucket(bucket)); assertEquals(10, bucket.getStartTimeStamp()); assertEquals(20, bucket.getEndTimeStamp()); assertBucketMatches(uid1Entry1, bucket); assertTrue(stats.getNextBucket(bucket)); assertEquals(20, bucket.getStartTimeStamp()); assertEquals(30, bucket.getEndTimeStamp()); assertBucketMatches(uid1Entry2, bucket); // 30 -> 40: contains uid2Entry1 and half of uid2Entry2 assertTrue(stats.getNextBucket(bucket)); assertEquals(30, bucket.getStartTimeStamp()); assertEquals(40, bucket.getEndTimeStamp()); assertEquals(225, bucket.getRxBytes()); assertEquals(15, bucket.getRxPackets()); assertEquals(375, bucket.getTxBytes()); assertEquals(30, bucket.getTxPackets()); // 40 -> 50: contains half of uid2Entry2 assertTrue(stats.getNextBucket(bucket)); assertEquals(40, bucket.getStartTimeStamp()); assertEquals(50, bucket.getEndTimeStamp()); assertEquals(75, bucket.getRxBytes()); assertEquals(5, bucket.getRxPackets()); assertEquals(125, bucket.getTxBytes()); assertEquals(10, bucket.getTxPackets()); assertFalse(stats.hasNextBucket()); } @Test public void testQueryDetails_NoSubscriberId() throws RemoteException { final long startTime = 1; final long endTime = 100; final int uid1 = 10001; final int uid2 = 10002; when(mService.openSessionForUsageStats(anyInt(), anyString())).thenReturn(mStatsSession); when(mStatsSession.getRelevantUids()).thenReturn(new int[] { uid1, uid2 }); NetworkStats stats = mManager.queryDetails( ConnectivityManager.TYPE_MOBILE, null, startTime, endTime); when(mStatsSession.getHistoryIntervalForUid(any(NetworkTemplate.class), anyInt(), anyInt(), anyInt(), anyInt(), anyLong(), anyLong())) .thenReturn(new NetworkStatsHistory(10, 0)); verify(mStatsSession, times(1)).getHistoryIntervalForUid( argThat((NetworkTemplate t) -> // No subscriberId: MATCH_MOBILE_WILDCARD template t.getMatchRule() == NetworkTemplate.MATCH_MOBILE_WILDCARD), eq(uid1), eq(android.net.NetworkStats.SET_ALL), eq(android.net.NetworkStats.TAG_NONE), eq(NetworkStatsHistory.FIELD_ALL), eq(startTime), eq(endTime)); verify(mStatsSession, times(1)).getHistoryIntervalForUid( argThat((NetworkTemplate t) -> // No subscriberId: MATCH_MOBILE_WILDCARD template t.getMatchRule() == NetworkTemplate.MATCH_MOBILE_WILDCARD), eq(uid2), eq(android.net.NetworkStats.SET_ALL), eq(android.net.NetworkStats.TAG_NONE), eq(NetworkStatsHistory.FIELD_ALL), eq(startTime), eq(endTime)); assertFalse(stats.hasNextBucket()); } private void assertBucketMatches(Entry expected, NetworkStats.Bucket actual) { assertEquals(expected.uid, actual.getUid()); assertEquals(expected.rxBytes, actual.getRxBytes()); assertEquals(expected.rxPackets, actual.getRxPackets()); assertEquals(expected.txBytes, actual.getTxBytes()); assertEquals(expected.txPackets, actual.getTxPackets()); } } Loading
core/java/android/app/usage/NetworkStats.java +2 −4 Original line number Diff line number Diff line Loading @@ -24,7 +24,6 @@ import android.net.NetworkStatsHistory; import android.net.NetworkTemplate; import android.net.TrafficStats; import android.os.RemoteException; import android.os.ServiceManager; import android.util.IntArray; import android.util.Log; Loading Loading @@ -98,9 +97,8 @@ public final class NetworkStats implements AutoCloseable { /** @hide */ NetworkStats(Context context, NetworkTemplate template, int flags, long startTimestamp, long endTimestamp) throws RemoteException, SecurityException { final INetworkStatsService statsService = INetworkStatsService.Stub.asInterface( ServiceManager.getService(Context.NETWORK_STATS_SERVICE)); long endTimestamp, INetworkStatsService statsService) throws RemoteException, SecurityException { // Open network stats session mSession = statsService.openSessionForUsageStats(flags, context.getOpPackageName()); mCloseGuard.open("close"); Loading
core/java/android/app/usage/NetworkStatsManager.java +25 −15 Original line number Diff line number Diff line Loading @@ -37,6 +37,8 @@ import android.os.ServiceManager; import android.os.ServiceManager.ServiceNotFoundException; import android.util.Log; import com.android.internal.annotations.VisibleForTesting; /** * Provides access to network usage history and statistics. Usage data is collected in * discrete bins of time called 'Buckets'. See {@link NetworkStats.Bucket} for details. Loading Loading @@ -107,9 +109,15 @@ public class NetworkStatsManager { * {@hide} */ public NetworkStatsManager(Context context) throws ServiceNotFoundException { this(context, INetworkStatsService.Stub.asInterface( ServiceManager.getServiceOrThrow(Context.NETWORK_STATS_SERVICE))); } /** @hide */ @VisibleForTesting public NetworkStatsManager(Context context, INetworkStatsService service) { mContext = context; mService = INetworkStatsService.Stub.asInterface( ServiceManager.getServiceOrThrow(Context.NETWORK_STATS_SERVICE)); mService = service; setPollOnOpen(true); } Loading @@ -135,7 +143,8 @@ public class NetworkStatsManager { public Bucket querySummaryForDevice(NetworkTemplate template, long startTime, long endTime) throws SecurityException, RemoteException { Bucket bucket = null; NetworkStats stats = new NetworkStats(mContext, template, mFlags, startTime, endTime); NetworkStats stats = new NetworkStats(mContext, template, mFlags, startTime, endTime, mService); bucket = stats.getDeviceSummaryForNetwork(); stats.close(); Loading Loading @@ -208,7 +217,7 @@ public class NetworkStatsManager { } NetworkStats stats; stats = new NetworkStats(mContext, template, mFlags, startTime, endTime); stats = new NetworkStats(mContext, template, mFlags, startTime, endTime, mService); stats.startSummaryEnumeration(); stats.close(); Loading Loading @@ -245,7 +254,7 @@ public class NetworkStatsManager { } NetworkStats result; result = new NetworkStats(mContext, template, mFlags, startTime, endTime); result = new NetworkStats(mContext, template, mFlags, startTime, endTime, mService); result.startSummaryEnumeration(); return result; Loading Loading @@ -295,7 +304,7 @@ public class NetworkStatsManager { NetworkStats result; try { result = new NetworkStats(mContext, template, mFlags, startTime, endTime); result = new NetworkStats(mContext, template, mFlags, startTime, endTime, mService); result.startHistoryEnumeration(uid, tag); } catch (RemoteException e) { Log.e(TAG, "Error while querying stats for uid=" + uid + " tag=" + tag, e); Loading Loading @@ -341,7 +350,7 @@ public class NetworkStatsManager { } NetworkStats result; result = new NetworkStats(mContext, template, mFlags, startTime, endTime); result = new NetworkStats(mContext, template, mFlags, startTime, endTime, mService); result.startUserUidEnumeration(); return result; } Loading Loading @@ -451,20 +460,21 @@ public class NetworkStatsManager { } private static NetworkTemplate createTemplate(int networkType, String subscriberId) { NetworkTemplate template = null; final NetworkTemplate template; switch (networkType) { case ConnectivityManager.TYPE_MOBILE: { template = NetworkTemplate.buildTemplateMobileAll(subscriberId); } break; case ConnectivityManager.TYPE_WIFI: { case ConnectivityManager.TYPE_MOBILE: template = subscriberId == null ? NetworkTemplate.buildTemplateMobileWildcard() : NetworkTemplate.buildTemplateMobileAll(subscriberId); break; case ConnectivityManager.TYPE_WIFI: template = NetworkTemplate.buildTemplateWifiWildcard(); } break; default: { break; default: throw new IllegalArgumentException("Cannot create template for network type " + networkType + ", subscriberId '" + NetworkIdentity.scrubSubscriberId(subscriberId) + "'."); } } return template; } Loading
tests/net/java/android/app/usage/NetworkStatsManagerTest.java 0 → 100644 +213 −0 Original line number Diff line number Diff line /* * Copyright (C) 2018 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.app.usage; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertFalse; import static junit.framework.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.net.ConnectivityManager; import android.net.INetworkStatsService; import android.net.INetworkStatsSession; import android.net.NetworkStats.Entry; import android.net.NetworkStatsHistory; import android.net.NetworkTemplate; import android.os.RemoteException; import android.support.test.InstrumentationRegistry; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.mockito.invocation.InvocationOnMock; @RunWith(AndroidJUnit4.class) @SmallTest public class NetworkStatsManagerTest { private @Mock INetworkStatsService mService; private @Mock INetworkStatsSession mStatsSession; private NetworkStatsManager mManager; // TODO: change to NetworkTemplate.MATCH_MOBILE once internal constant rename is merged to aosp. private static final int MATCH_MOBILE_ALL = 1; @Before public void setUp() { MockitoAnnotations.initMocks(this); mManager = new NetworkStatsManager(InstrumentationRegistry.getContext(), mService); } @Test public void testQueryDetails() throws RemoteException { final String subscriberId = "subid"; final long startTime = 1; final long endTime = 100; final int uid1 = 10001; final int uid2 = 10002; final int uid3 = 10003; Entry uid1Entry1 = new Entry("if1", uid1, android.net.NetworkStats.SET_DEFAULT, android.net.NetworkStats.TAG_NONE, 100, 10, 200, 20, 0); Entry uid1Entry2 = new Entry( "if2", uid1, android.net.NetworkStats.SET_DEFAULT, android.net.NetworkStats.TAG_NONE, 100, 10, 200, 20, 0); Entry uid2Entry1 = new Entry("if1", uid2, android.net.NetworkStats.SET_DEFAULT, android.net.NetworkStats.TAG_NONE, 150, 10, 250, 20, 0); Entry uid2Entry2 = new Entry( "if2", uid2, android.net.NetworkStats.SET_DEFAULT, android.net.NetworkStats.TAG_NONE, 150, 10, 250, 20, 0); NetworkStatsHistory history1 = new NetworkStatsHistory(10, 2); history1.recordData(10, 20, uid1Entry1); history1.recordData(20, 30, uid1Entry2); NetworkStatsHistory history2 = new NetworkStatsHistory(10, 2); history1.recordData(30, 40, uid2Entry1); history1.recordData(35, 45, uid2Entry2); when(mService.openSessionForUsageStats(anyInt(), anyString())).thenReturn(mStatsSession); when(mStatsSession.getRelevantUids()).thenReturn(new int[] { uid1, uid2, uid3 }); when(mStatsSession.getHistoryIntervalForUid(any(NetworkTemplate.class), eq(uid1), eq(android.net.NetworkStats.SET_ALL), eq(android.net.NetworkStats.TAG_NONE), eq(NetworkStatsHistory.FIELD_ALL), eq(startTime), eq(endTime))) .then((InvocationOnMock inv) -> { NetworkTemplate template = inv.getArgument(0); assertEquals(MATCH_MOBILE_ALL, template.getMatchRule()); assertEquals(subscriberId, template.getSubscriberId()); return history1; }); when(mStatsSession.getHistoryIntervalForUid(any(NetworkTemplate.class), eq(uid2), eq(android.net.NetworkStats.SET_ALL), eq(android.net.NetworkStats.TAG_NONE), eq(NetworkStatsHistory.FIELD_ALL), eq(startTime), eq(endTime))) .then((InvocationOnMock inv) -> { NetworkTemplate template = inv.getArgument(0); assertEquals(MATCH_MOBILE_ALL, template.getMatchRule()); assertEquals(subscriberId, template.getSubscriberId()); return history2; }); NetworkStats stats = mManager.queryDetails( ConnectivityManager.TYPE_MOBILE, subscriberId, startTime, endTime); NetworkStats.Bucket bucket = new NetworkStats.Bucket(); // First 2 buckets exactly match entry timings assertTrue(stats.getNextBucket(bucket)); assertEquals(10, bucket.getStartTimeStamp()); assertEquals(20, bucket.getEndTimeStamp()); assertBucketMatches(uid1Entry1, bucket); assertTrue(stats.getNextBucket(bucket)); assertEquals(20, bucket.getStartTimeStamp()); assertEquals(30, bucket.getEndTimeStamp()); assertBucketMatches(uid1Entry2, bucket); // 30 -> 40: contains uid2Entry1 and half of uid2Entry2 assertTrue(stats.getNextBucket(bucket)); assertEquals(30, bucket.getStartTimeStamp()); assertEquals(40, bucket.getEndTimeStamp()); assertEquals(225, bucket.getRxBytes()); assertEquals(15, bucket.getRxPackets()); assertEquals(375, bucket.getTxBytes()); assertEquals(30, bucket.getTxPackets()); // 40 -> 50: contains half of uid2Entry2 assertTrue(stats.getNextBucket(bucket)); assertEquals(40, bucket.getStartTimeStamp()); assertEquals(50, bucket.getEndTimeStamp()); assertEquals(75, bucket.getRxBytes()); assertEquals(5, bucket.getRxPackets()); assertEquals(125, bucket.getTxBytes()); assertEquals(10, bucket.getTxPackets()); assertFalse(stats.hasNextBucket()); } @Test public void testQueryDetails_NoSubscriberId() throws RemoteException { final long startTime = 1; final long endTime = 100; final int uid1 = 10001; final int uid2 = 10002; when(mService.openSessionForUsageStats(anyInt(), anyString())).thenReturn(mStatsSession); when(mStatsSession.getRelevantUids()).thenReturn(new int[] { uid1, uid2 }); NetworkStats stats = mManager.queryDetails( ConnectivityManager.TYPE_MOBILE, null, startTime, endTime); when(mStatsSession.getHistoryIntervalForUid(any(NetworkTemplate.class), anyInt(), anyInt(), anyInt(), anyInt(), anyLong(), anyLong())) .thenReturn(new NetworkStatsHistory(10, 0)); verify(mStatsSession, times(1)).getHistoryIntervalForUid( argThat((NetworkTemplate t) -> // No subscriberId: MATCH_MOBILE_WILDCARD template t.getMatchRule() == NetworkTemplate.MATCH_MOBILE_WILDCARD), eq(uid1), eq(android.net.NetworkStats.SET_ALL), eq(android.net.NetworkStats.TAG_NONE), eq(NetworkStatsHistory.FIELD_ALL), eq(startTime), eq(endTime)); verify(mStatsSession, times(1)).getHistoryIntervalForUid( argThat((NetworkTemplate t) -> // No subscriberId: MATCH_MOBILE_WILDCARD template t.getMatchRule() == NetworkTemplate.MATCH_MOBILE_WILDCARD), eq(uid2), eq(android.net.NetworkStats.SET_ALL), eq(android.net.NetworkStats.TAG_NONE), eq(NetworkStatsHistory.FIELD_ALL), eq(startTime), eq(endTime)); assertFalse(stats.hasNextBucket()); } private void assertBucketMatches(Entry expected, NetworkStats.Bucket actual) { assertEquals(expected.uid, actual.getUid()); assertEquals(expected.rxBytes, actual.getRxBytes()); assertEquals(expected.rxPackets, actual.getRxPackets()); assertEquals(expected.txBytes, actual.getTxBytes()); assertEquals(expected.txPackets, actual.getTxPackets()); } }