Loading services/core/java/com/android/server/net/NetworkStatsService.java +21 −2 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import static android.content.Intent.ACTION_UID_REMOVED; import static android.content.Intent.ACTION_USER_REMOVED; import static android.content.Intent.EXTRA_UID; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; import static android.net.NetworkIdentity.SUBTYPE_COMBINED; import static android.net.NetworkStack.checkNetworkStackPermission; import static android.net.NetworkStats.DEFAULT_NETWORK_ALL; Loading Loading @@ -65,6 +66,7 @@ import static android.provider.Settings.Global.NETSTATS_UID_TAG_BUCKET_DURATION; import static android.provider.Settings.Global.NETSTATS_UID_TAG_DELETE_AGE; import static android.provider.Settings.Global.NETSTATS_UID_TAG_PERSIST_BYTES; import static android.provider.Settings.Global.NETSTATS_UID_TAG_ROTATE_AGE; import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID; import static android.text.format.DateUtils.DAY_IN_MILLIS; import static android.text.format.DateUtils.HOUR_IN_MILLIS; import static android.text.format.DateUtils.MINUTE_IN_MILLIS; Loading Loading @@ -100,7 +102,9 @@ import android.net.NetworkStateSnapshot; import android.net.NetworkStats; import android.net.NetworkStats.NonMonotonicObserver; import android.net.NetworkStatsHistory; import android.net.NetworkSpecifier; import android.net.NetworkTemplate; import android.net.TelephonyNetworkSpecifier; import android.net.TrafficStats; import android.net.UnderlyingNetworkInfo; import android.net.Uri; Loading Loading @@ -1320,8 +1324,9 @@ public class NetworkStatsService extends INetworkStatsService.Stub { ident.getSubType(), ident.getSubscriberId(), ident.getNetworkId(), ident.getRoaming(), true /* metered */, true /* onDefaultNetwork */, ident.getOemManaged()); findOrCreateNetworkIdentitySet(mActiveIfaces, IFACE_VT).add(vtIdent); findOrCreateNetworkIdentitySet(mActiveUidIfaces, IFACE_VT).add(vtIdent); final String ifaceVt = IFACE_VT + getSubIdForMobile(snapshot); findOrCreateNetworkIdentitySet(mActiveIfaces, ifaceVt).add(vtIdent); findOrCreateNetworkIdentitySet(mActiveUidIfaces, ifaceVt).add(vtIdent); } if (isMobile) { Loading Loading @@ -1377,6 +1382,20 @@ public class NetworkStatsService extends INetworkStatsService.Stub { mMobileIfaces = mobileIfaces.toArray(new String[mobileIfaces.size()]); } private static int getSubIdForMobile(@NonNull NetworkStateSnapshot state) { if (!state.networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) { throw new IllegalArgumentException("Mobile state need capability TRANSPORT_CELLULAR"); } final NetworkSpecifier spec = state.networkCapabilities.getNetworkSpecifier(); if (spec instanceof TelephonyNetworkSpecifier) { return ((TelephonyNetworkSpecifier) spec).getSubscriptionId(); } else { Slog.wtf(TAG, "getSubIdForState invalid NetworkSpecifier"); return INVALID_SUBSCRIPTION_ID; } } /** * For networks with {@code TRANSPORT_CELLULAR}, get subType that was obtained through * {@link PhoneStateListener}. Otherwise, return 0 given that other networks with different Loading tests/net/java/com/android/server/net/NetworkStatsServiceTest.java +86 −0 Original line number Diff line number Diff line Loading @@ -89,6 +89,7 @@ import android.net.NetworkStats; import android.net.NetworkStatsHistory; import android.net.NetworkTemplate; import android.net.UnderlyingNetworkInfo; import android.net.TelephonyNetworkSpecifier; import android.net.netstats.provider.INetworkStatsProviderCallback; import android.os.ConditionVariable; import android.os.Handler; Loading Loading @@ -1279,6 +1280,77 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { provider.assertNoCallback(); } @Test public void testDualVilteProviderStats() throws Exception { // Pretend that network comes online. expectDefaultSettings(); final int subId1 = 1; final int subId2 = 2; final NetworkStateSnapshot[] states = new NetworkStateSnapshot[]{ buildImsState(IMSI_1, subId1, TEST_IFACE), buildImsState(IMSI_2, subId2, TEST_IFACE2)}; expectNetworkStatsSummary(buildEmptyStats()); expectNetworkStatsUidDetail(buildEmptyStats()); // Register custom provider and retrieve callback. final TestableNetworkStatsProviderBinder provider = new TestableNetworkStatsProviderBinder(); final INetworkStatsProviderCallback cb = mService.registerNetworkStatsProvider("TEST", provider); assertNotNull(cb); mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states), new UnderlyingNetworkInfo[0]); // Verifies that one requestStatsUpdate will be called during iface update. provider.expectOnRequestStatsUpdate(0 /* unused */); // Create some initial traffic and report to the service. incrementCurrentTime(HOUR_IN_MILLIS); final String vtIface1 = NetworkStats.IFACE_VT + subId1; final String vtIface2 = NetworkStats.IFACE_VT + subId2; final NetworkStats expectedStats = new NetworkStats(0L, 1) .addEntry(new NetworkStats.Entry(vtIface1, UID_RED, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, DEFAULT_NETWORK_YES, 128L, 2L, 128L, 2L, 1L)) .addEntry(new NetworkStats.Entry(vtIface2, UID_RED, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, DEFAULT_NETWORK_YES, 64L, 1L, 64L, 1L, 1L)); cb.notifyStatsUpdated(0 /* unused */, expectedStats, expectedStats); // Make another empty mutable stats object. This is necessary since the new NetworkStats // object will be used to compare with the old one in NetworkStatsRecoder, two of them // cannot be the same object. expectNetworkStatsUidDetail(buildEmptyStats()); forcePollAndWaitForIdle(); // Verifies that one requestStatsUpdate and setAlert will be called during polling. provider.expectOnRequestStatsUpdate(0 /* unused */); provider.expectOnSetAlert(MB_IN_BYTES); // Verifies that service recorded history, does not verify uid tag part. assertUidTotal(sTemplateImsi1, UID_RED, 128L, 2L, 128L, 2L, 1); // Verifies that onStatsUpdated updates the stats accordingly. NetworkStats stats = mSession.getSummaryForAllUid( sTemplateImsi1, Long.MIN_VALUE, Long.MAX_VALUE, true); assertEquals(1, stats.size()); assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, DEFAULT_NETWORK_YES, 128L, 2L, 128L, 2L, 1L); stats = mSession.getSummaryForAllUid( sTemplateImsi2, Long.MIN_VALUE, Long.MAX_VALUE, true); assertEquals(1, stats.size()); assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, DEFAULT_NETWORK_YES, 64L, 1L, 64L, 1L, 1L); // Verifies that unregister the callback will remove the provider from service. cb.unregister(); forcePollAndWaitForIdle(); provider.assertNoCallback(); } @Test public void testStatsProviderSetAlert() throws Exception { // Pretend that network comes online. Loading Loading @@ -1616,6 +1688,20 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { TYPE_MOBILE); } private static NetworkStateSnapshot buildImsState( String subscriberId, int subId, String ifaceName) { final LinkProperties prop = new LinkProperties(); prop.setInterfaceName(ifaceName); final NetworkCapabilities capabilities = new NetworkCapabilities(); capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED, true); capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, true); capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_IMS, true); capabilities.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR); capabilities.setNetworkSpecifier(new TelephonyNetworkSpecifier(subId)); return new NetworkStateSnapshot( MOBILE_NETWORK, capabilities, prop, subscriberId, TYPE_MOBILE); } private long getElapsedRealtime() { return mElapsedRealtime; } Loading Loading
services/core/java/com/android/server/net/NetworkStatsService.java +21 −2 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import static android.content.Intent.ACTION_UID_REMOVED; import static android.content.Intent.ACTION_USER_REMOVED; import static android.content.Intent.EXTRA_UID; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; import static android.net.NetworkIdentity.SUBTYPE_COMBINED; import static android.net.NetworkStack.checkNetworkStackPermission; import static android.net.NetworkStats.DEFAULT_NETWORK_ALL; Loading Loading @@ -65,6 +66,7 @@ import static android.provider.Settings.Global.NETSTATS_UID_TAG_BUCKET_DURATION; import static android.provider.Settings.Global.NETSTATS_UID_TAG_DELETE_AGE; import static android.provider.Settings.Global.NETSTATS_UID_TAG_PERSIST_BYTES; import static android.provider.Settings.Global.NETSTATS_UID_TAG_ROTATE_AGE; import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID; import static android.text.format.DateUtils.DAY_IN_MILLIS; import static android.text.format.DateUtils.HOUR_IN_MILLIS; import static android.text.format.DateUtils.MINUTE_IN_MILLIS; Loading Loading @@ -100,7 +102,9 @@ import android.net.NetworkStateSnapshot; import android.net.NetworkStats; import android.net.NetworkStats.NonMonotonicObserver; import android.net.NetworkStatsHistory; import android.net.NetworkSpecifier; import android.net.NetworkTemplate; import android.net.TelephonyNetworkSpecifier; import android.net.TrafficStats; import android.net.UnderlyingNetworkInfo; import android.net.Uri; Loading Loading @@ -1320,8 +1324,9 @@ public class NetworkStatsService extends INetworkStatsService.Stub { ident.getSubType(), ident.getSubscriberId(), ident.getNetworkId(), ident.getRoaming(), true /* metered */, true /* onDefaultNetwork */, ident.getOemManaged()); findOrCreateNetworkIdentitySet(mActiveIfaces, IFACE_VT).add(vtIdent); findOrCreateNetworkIdentitySet(mActiveUidIfaces, IFACE_VT).add(vtIdent); final String ifaceVt = IFACE_VT + getSubIdForMobile(snapshot); findOrCreateNetworkIdentitySet(mActiveIfaces, ifaceVt).add(vtIdent); findOrCreateNetworkIdentitySet(mActiveUidIfaces, ifaceVt).add(vtIdent); } if (isMobile) { Loading Loading @@ -1377,6 +1382,20 @@ public class NetworkStatsService extends INetworkStatsService.Stub { mMobileIfaces = mobileIfaces.toArray(new String[mobileIfaces.size()]); } private static int getSubIdForMobile(@NonNull NetworkStateSnapshot state) { if (!state.networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) { throw new IllegalArgumentException("Mobile state need capability TRANSPORT_CELLULAR"); } final NetworkSpecifier spec = state.networkCapabilities.getNetworkSpecifier(); if (spec instanceof TelephonyNetworkSpecifier) { return ((TelephonyNetworkSpecifier) spec).getSubscriptionId(); } else { Slog.wtf(TAG, "getSubIdForState invalid NetworkSpecifier"); return INVALID_SUBSCRIPTION_ID; } } /** * For networks with {@code TRANSPORT_CELLULAR}, get subType that was obtained through * {@link PhoneStateListener}. Otherwise, return 0 given that other networks with different Loading
tests/net/java/com/android/server/net/NetworkStatsServiceTest.java +86 −0 Original line number Diff line number Diff line Loading @@ -89,6 +89,7 @@ import android.net.NetworkStats; import android.net.NetworkStatsHistory; import android.net.NetworkTemplate; import android.net.UnderlyingNetworkInfo; import android.net.TelephonyNetworkSpecifier; import android.net.netstats.provider.INetworkStatsProviderCallback; import android.os.ConditionVariable; import android.os.Handler; Loading Loading @@ -1279,6 +1280,77 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { provider.assertNoCallback(); } @Test public void testDualVilteProviderStats() throws Exception { // Pretend that network comes online. expectDefaultSettings(); final int subId1 = 1; final int subId2 = 2; final NetworkStateSnapshot[] states = new NetworkStateSnapshot[]{ buildImsState(IMSI_1, subId1, TEST_IFACE), buildImsState(IMSI_2, subId2, TEST_IFACE2)}; expectNetworkStatsSummary(buildEmptyStats()); expectNetworkStatsUidDetail(buildEmptyStats()); // Register custom provider and retrieve callback. final TestableNetworkStatsProviderBinder provider = new TestableNetworkStatsProviderBinder(); final INetworkStatsProviderCallback cb = mService.registerNetworkStatsProvider("TEST", provider); assertNotNull(cb); mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states), new UnderlyingNetworkInfo[0]); // Verifies that one requestStatsUpdate will be called during iface update. provider.expectOnRequestStatsUpdate(0 /* unused */); // Create some initial traffic and report to the service. incrementCurrentTime(HOUR_IN_MILLIS); final String vtIface1 = NetworkStats.IFACE_VT + subId1; final String vtIface2 = NetworkStats.IFACE_VT + subId2; final NetworkStats expectedStats = new NetworkStats(0L, 1) .addEntry(new NetworkStats.Entry(vtIface1, UID_RED, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, DEFAULT_NETWORK_YES, 128L, 2L, 128L, 2L, 1L)) .addEntry(new NetworkStats.Entry(vtIface2, UID_RED, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, DEFAULT_NETWORK_YES, 64L, 1L, 64L, 1L, 1L)); cb.notifyStatsUpdated(0 /* unused */, expectedStats, expectedStats); // Make another empty mutable stats object. This is necessary since the new NetworkStats // object will be used to compare with the old one in NetworkStatsRecoder, two of them // cannot be the same object. expectNetworkStatsUidDetail(buildEmptyStats()); forcePollAndWaitForIdle(); // Verifies that one requestStatsUpdate and setAlert will be called during polling. provider.expectOnRequestStatsUpdate(0 /* unused */); provider.expectOnSetAlert(MB_IN_BYTES); // Verifies that service recorded history, does not verify uid tag part. assertUidTotal(sTemplateImsi1, UID_RED, 128L, 2L, 128L, 2L, 1); // Verifies that onStatsUpdated updates the stats accordingly. NetworkStats stats = mSession.getSummaryForAllUid( sTemplateImsi1, Long.MIN_VALUE, Long.MAX_VALUE, true); assertEquals(1, stats.size()); assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, DEFAULT_NETWORK_YES, 128L, 2L, 128L, 2L, 1L); stats = mSession.getSummaryForAllUid( sTemplateImsi2, Long.MIN_VALUE, Long.MAX_VALUE, true); assertEquals(1, stats.size()); assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, DEFAULT_NETWORK_YES, 64L, 1L, 64L, 1L, 1L); // Verifies that unregister the callback will remove the provider from service. cb.unregister(); forcePollAndWaitForIdle(); provider.assertNoCallback(); } @Test public void testStatsProviderSetAlert() throws Exception { // Pretend that network comes online. Loading Loading @@ -1616,6 +1688,20 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { TYPE_MOBILE); } private static NetworkStateSnapshot buildImsState( String subscriberId, int subId, String ifaceName) { final LinkProperties prop = new LinkProperties(); prop.setInterfaceName(ifaceName); final NetworkCapabilities capabilities = new NetworkCapabilities(); capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED, true); capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, true); capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_IMS, true); capabilities.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR); capabilities.setNetworkSpecifier(new TelephonyNetworkSpecifier(subId)); return new NetworkStateSnapshot( MOBILE_NETWORK, capabilities, prop, subscriberId, TYPE_MOBILE); } private long getElapsedRealtime() { return mElapsedRealtime; } Loading