diff options
5 files changed, 291 insertions, 8 deletions
diff --git a/tests/net/java/android/net/NetworkIdentityTest.kt b/tests/net/java/android/net/NetworkIdentityTest.kt new file mode 100644 index 000000000000..eb2b85c14578 --- /dev/null +++ b/tests/net/java/android/net/NetworkIdentityTest.kt @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2021 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.net + +import android.net.NetworkIdentity.OEM_NONE +import android.net.NetworkIdentity.OEM_PAID +import android.net.NetworkIdentity.OEM_PRIVATE +import android.net.NetworkIdentity.getOemBitfield +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.JUnit4 +import kotlin.test.assertEquals + +@RunWith(JUnit4::class) +class NetworkIdentityTest { + @Test + fun testGetOemBitfield() { + val oemNone = NetworkCapabilities().apply { + setCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PAID, false) + setCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE, false) + } + val oemPaid = NetworkCapabilities().apply { + setCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PAID, true) + setCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE, false) + } + val oemPrivate = NetworkCapabilities().apply { + setCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PAID, false) + setCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE, true) + } + val oemAll = NetworkCapabilities().apply { + setCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PAID, true) + setCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE, true) + } + + assertEquals(getOemBitfield(oemNone), OEM_NONE) + assertEquals(getOemBitfield(oemPaid), OEM_PAID) + assertEquals(getOemBitfield(oemPrivate), OEM_PRIVATE) + assertEquals(getOemBitfield(oemAll), OEM_PAID or OEM_PRIVATE) + } +} diff --git a/tests/net/java/android/net/NetworkTemplateTest.kt b/tests/net/java/android/net/NetworkTemplateTest.kt index b39555d15dcb..27224c216db3 100644 --- a/tests/net/java/android/net/NetworkTemplateTest.kt +++ b/tests/net/java/android/net/NetworkTemplateTest.kt @@ -20,14 +20,23 @@ import android.content.Context import android.net.ConnectivityManager.TYPE_MOBILE import android.net.ConnectivityManager.TYPE_WIFI import android.net.NetworkIdentity.SUBTYPE_COMBINED +import android.net.NetworkIdentity.OEM_NONE; +import android.net.NetworkIdentity.OEM_PAID; +import android.net.NetworkIdentity.OEM_PRIVATE; import android.net.NetworkIdentity.buildNetworkIdentity import android.net.NetworkStats.DEFAULT_NETWORK_ALL import android.net.NetworkStats.METERED_ALL import android.net.NetworkStats.ROAMING_ALL +import android.net.NetworkTemplate.MATCH_ETHERNET import android.net.NetworkTemplate.MATCH_MOBILE +import android.net.NetworkTemplate.MATCH_MOBILE_WILDCARD import android.net.NetworkTemplate.MATCH_WIFI +import android.net.NetworkTemplate.MATCH_WIFI_WILDCARD import android.net.NetworkTemplate.NETWORK_TYPE_5G_NSA import android.net.NetworkTemplate.NETWORK_TYPE_ALL +import android.net.NetworkTemplate.OEM_MANAGED_ALL +import android.net.NetworkTemplate.OEM_MANAGED_NO +import android.net.NetworkTemplate.OEM_MANAGED_YES import android.net.NetworkTemplate.buildTemplateMobileWithRatType import android.telephony.TelephonyManager import com.android.testutils.assertParcelSane @@ -37,9 +46,11 @@ import org.junit.runner.RunWith import org.junit.runners.JUnit4 import org.mockito.Mockito.mock import org.mockito.MockitoAnnotations +import kotlin.test.assertEquals import kotlin.test.assertFalse import kotlin.test.assertNotEquals import kotlin.test.assertTrue +import kotlin.test.fail private const val TEST_IMSI1 = "imsi1" private const val TEST_IMSI2 = "imsi2" @@ -57,13 +68,18 @@ class NetworkTemplateTest { private fun buildNetworkState( type: Int, subscriberId: String? = null, - ssid: String? = null + ssid: String? = null, + oemManaged: Int = OEM_NONE, ): NetworkState { val lp = LinkProperties() val caps = NetworkCapabilities().apply { setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED, false) setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, true) setSSID(ssid) + setCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PAID, + (oemManaged and OEM_PAID) == OEM_PAID) + setCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE, + (oemManaged and OEM_PRIVATE) == OEM_PRIVATE) } return NetworkState(type, lp, caps, mock(Network::class.java), subscriberId) } @@ -136,11 +152,15 @@ class NetworkTemplateTest { @Test fun testParcelUnparcel() { val templateMobile = NetworkTemplate(MATCH_MOBILE, TEST_IMSI1, null, null, METERED_ALL, - ROAMING_ALL, DEFAULT_NETWORK_ALL, TelephonyManager.NETWORK_TYPE_LTE) + ROAMING_ALL, DEFAULT_NETWORK_ALL, TelephonyManager.NETWORK_TYPE_LTE, + OEM_MANAGED_ALL) val templateWifi = NetworkTemplate(MATCH_WIFI, null, null, TEST_SSID1, METERED_ALL, - ROAMING_ALL, DEFAULT_NETWORK_ALL, 0) - assertParcelSane(templateMobile, 8) - assertParcelSane(templateWifi, 8) + ROAMING_ALL, DEFAULT_NETWORK_ALL, 0, OEM_MANAGED_ALL) + val templateOem = NetworkTemplate(MATCH_MOBILE, null, null, null, METERED_ALL, + ROAMING_ALL, DEFAULT_NETWORK_ALL, 0, OEM_MANAGED_YES) + assertParcelSane(templateMobile, 9) + assertParcelSane(templateWifi, 9) + assertParcelSane(templateOem, 9) } // Verify NETWORK_TYPE_* constants in NetworkTemplate do not conflict with @@ -152,4 +172,81 @@ class NetworkTemplateTest { assertNotEquals(NETWORK_TYPE_5G_NSA, ratType) } } + + @Test + fun testOemNetworkConstants() { + val constantValues = arrayOf(OEM_MANAGED_YES, OEM_MANAGED_ALL, OEM_MANAGED_NO, + OEM_PAID, OEM_PRIVATE, OEM_PAID or OEM_PRIVATE) + + // Verify that "not OEM managed network" constants are equal. + assertEquals(OEM_MANAGED_NO, OEM_NONE); + + // Verify the constants don't conflict. + assertEquals(constantValues.size, constantValues.distinct().count()) + } + + /** + * Helper to enumerate and assert OEM managed wifi and mobile {@code NetworkTemplate}s match + * their the appropriate OEM managed {@code NetworkIdentity}s. + * + * @param networkType {@code TYPE_MOBILE} or {@code TYPE_WIFI} + * @param matchType A match rule from {@code NetworkTemplate.MATCH_*} corresponding to the + * networkType. + * @param subscriberId To be populated with {@code TEST_IMSI*} only if networkType is + * {@code TYPE_MOBILE}. May be left as null when matchType is + * {@link NetworkTemplate.MATCH_MOBILE_WILDCARD}. + * @param templateSsid Top be populated with {@code TEST_SSID*} only if networkType is + * {@code TYPE_WIFI}. May be left as null when matchType is + * {@link NetworkTemplate.MATCH_WIFI_WILDCARD}. + * @param identSsid If networkType is {@code TYPE_WIFI}, this value must *NOT* be null. Provide + * one of {@code TEST_SSID*}. + */ + private fun matchOemManagedIdent(networkType: Int, matchType:Int, subscriberId: String? = null, + templateSsid: String? = null, identSsid: String? = null) { + val oemManagedStates = arrayOf(OEM_NONE, OEM_PAID, OEM_PRIVATE, OEM_PAID or OEM_PRIVATE) + // A null subscriberId needs a null matchSubscriberIds argument as well. + val matchSubscriberIds = if (subscriberId == null) null else arrayOf(subscriberId) + + val templateOemYes = NetworkTemplate(matchType, subscriberId, matchSubscriberIds, + templateSsid, METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, + OEM_MANAGED_YES) + val templateOemAll = NetworkTemplate(matchType, subscriberId, matchSubscriberIds, + templateSsid, METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, + OEM_MANAGED_ALL) + + for (identityOemManagedState in oemManagedStates) { + val ident = buildNetworkIdentity(mockContext, buildNetworkState(networkType, + subscriberId, identSsid, identityOemManagedState), /*defaultNetwork=*/false, + /*subType=*/0) + + // Create a template with each OEM managed type and match it against the NetworkIdentity + for (templateOemManagedState in oemManagedStates) { + val template = NetworkTemplate(matchType, subscriberId, matchSubscriberIds, + templateSsid, METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, + NETWORK_TYPE_ALL, templateOemManagedState) + if (identityOemManagedState == templateOemManagedState) { + template.assertMatches(ident) + } else { + template.assertDoesNotMatch(ident) + } + } + // OEM_MANAGED_ALL ignores OEM state. + templateOemAll.assertMatches(ident) + if (identityOemManagedState == OEM_NONE) { + // OEM_MANAGED_YES matches everything except OEM_NONE. + templateOemYes.assertDoesNotMatch(ident) + } else { + templateOemYes.assertMatches(ident) + } + } + } + + @Test + fun testOemManagedMatchesIdent() { + matchOemManagedIdent(TYPE_MOBILE, MATCH_MOBILE, subscriberId = TEST_IMSI1) + matchOemManagedIdent(TYPE_MOBILE, MATCH_MOBILE_WILDCARD) + matchOemManagedIdent(TYPE_WIFI, MATCH_WIFI, templateSsid = TEST_SSID1, + identSsid = TEST_SSID1) + matchOemManagedIdent(TYPE_WIFI, MATCH_WIFI_WILDCARD, identSsid = TEST_SSID1) + } } diff --git a/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java b/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java index 435c3c0af817..505ff9b6a34b 100644 --- a/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java +++ b/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java @@ -17,6 +17,7 @@ package com.android.server.net; import static android.net.ConnectivityManager.TYPE_MOBILE; +import static android.net.NetworkIdentity.OEM_NONE; import static android.net.NetworkStats.SET_ALL; import static android.net.NetworkStats.SET_DEFAULT; import static android.net.NetworkStats.TAG_NONE; @@ -213,7 +214,7 @@ public class NetworkStatsCollectionTest { final NetworkStats.Entry entry = new NetworkStats.Entry(); final NetworkIdentitySet identSet = new NetworkIdentitySet(); identSet.add(new NetworkIdentity(TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UNKNOWN, - TEST_IMSI, null, false, true, true)); + TEST_IMSI, null, false, true, true, OEM_NONE)); int myUid = Process.myUid(); int otherUidInSameUser = Process.myUid() + 1; @@ -468,7 +469,7 @@ public class NetworkStatsCollectionTest { final NetworkStatsCollection large = new NetworkStatsCollection(HOUR_IN_MILLIS); final NetworkIdentitySet ident = new NetworkIdentitySet(); ident.add(new NetworkIdentity(ConnectivityManager.TYPE_MOBILE, -1, TEST_IMSI, null, - false, true, true)); + false, true, true, OEM_NONE)); large.recordData(ident, UID_ALL, SET_ALL, TAG_NONE, TIME_A, TIME_B, new NetworkStats.Entry(12_730_893_164L, 1, 0, 0, 0)); diff --git a/tests/net/java/com/android/server/net/NetworkStatsObserversTest.java b/tests/net/java/com/android/server/net/NetworkStatsObserversTest.java index 291efc74aa47..9fa1c50423d9 100644 --- a/tests/net/java/com/android/server/net/NetworkStatsObserversTest.java +++ b/tests/net/java/com/android/server/net/NetworkStatsObserversTest.java @@ -17,6 +17,7 @@ package com.android.server.net; import static android.net.ConnectivityManager.TYPE_MOBILE; +import static android.net.NetworkIdentity.OEM_NONE; import static android.net.NetworkStats.DEFAULT_NETWORK_NO; import static android.net.NetworkStats.DEFAULT_NETWORK_YES; import static android.net.NetworkStats.METERED_NO; @@ -220,7 +221,7 @@ public class NetworkStatsObserversTest { identSet.add(new NetworkIdentity( TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UNKNOWN, IMSI_1, null /* networkId */, false /* roaming */, true /* metered */, - true /* defaultNetwork */)); + true /* defaultNetwork */, OEM_NONE)); return identSet; } diff --git a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java index d644739ea25e..54d6fb9f2c12 100644 --- a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java +++ b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java @@ -21,6 +21,9 @@ import static android.content.Intent.EXTRA_UID; import static android.net.ConnectivityManager.TYPE_MOBILE; import static android.net.ConnectivityManager.TYPE_VPN; import static android.net.ConnectivityManager.TYPE_WIFI; +import static android.net.NetworkIdentity.OEM_NONE; +import static android.net.NetworkIdentity.OEM_PAID; +import static android.net.NetworkIdentity.OEM_PRIVATE; import static android.net.NetworkStats.DEFAULT_NETWORK_ALL; import static android.net.NetworkStats.DEFAULT_NETWORK_NO; import static android.net.NetworkStats.DEFAULT_NETWORK_YES; @@ -40,7 +43,10 @@ import static android.net.NetworkStats.TAG_ALL; import static android.net.NetworkStats.TAG_NONE; import static android.net.NetworkStats.UID_ALL; import static android.net.NetworkStatsHistory.FIELD_ALL; +import static android.net.NetworkTemplate.MATCH_MOBILE_WILDCARD; import static android.net.NetworkTemplate.NETWORK_TYPE_ALL; +import static android.net.NetworkTemplate.OEM_MANAGED_NO; +import static android.net.NetworkTemplate.OEM_MANAGED_YES; import static android.net.NetworkTemplate.buildTemplateMobileAll; import static android.net.NetworkTemplate.buildTemplateMobileWithRatType; import static android.net.NetworkTemplate.buildTemplateWifi; @@ -643,6 +649,116 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { assertUidTotal(template5g, UID_RED, 5L, 13L, 31L, 9L, 2); } + @Test + public void testMobileStatsOemManaged() throws Exception { + final NetworkTemplate templateOemPaid = new NetworkTemplate(MATCH_MOBILE_WILDCARD, + /*subscriberId=*/null, /*matchSubscriberIds=*/null, /*networkId=*/null, + METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_PAID); + + final NetworkTemplate templateOemPrivate = new NetworkTemplate(MATCH_MOBILE_WILDCARD, + /*subscriberId=*/null, /*matchSubscriberIds=*/null, /*networkId=*/null, + METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_PRIVATE); + + final NetworkTemplate templateOemAll = new NetworkTemplate(MATCH_MOBILE_WILDCARD, + /*subscriberId=*/null, /*matchSubscriberIds=*/null, /*networkId=*/null, + METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, + OEM_PAID | OEM_PRIVATE); + + final NetworkTemplate templateOemYes = new NetworkTemplate(MATCH_MOBILE_WILDCARD, + /*subscriberId=*/null, /*matchSubscriberIds=*/null, /*networkId=*/null, + METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_MANAGED_YES); + + final NetworkTemplate templateOemNone = new NetworkTemplate(MATCH_MOBILE_WILDCARD, + /*subscriberId=*/null, /*matchSubscriberIds=*/null, /*networkId=*/null, + METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_MANAGED_NO); + + // OEM_PAID network comes online. + NetworkState[] states = new NetworkState[]{buildOemManagedMobileState(IMSI_1, false, + new int[]{NetworkCapabilities.NET_CAPABILITY_OEM_PAID})}; + expectNetworkStatsSummary(buildEmptyStats()); + expectNetworkStatsUidDetail(buildEmptyStats()); + mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states), + new UnderlyingNetworkInfo[0]); + + // Create some traffic. + incrementCurrentTime(MINUTE_IN_MILLIS); + expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1) + .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, + 36L, 41L, 24L, 96L, 0L))); + forcePollAndWaitForIdle(); + + // OEM_PRIVATE network comes online. + states = new NetworkState[]{buildOemManagedMobileState(IMSI_1, false, + new int[]{NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE})}; + expectNetworkStatsSummary(buildEmptyStats()); + expectNetworkStatsUidDetail(buildEmptyStats()); + mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states), + new UnderlyingNetworkInfo[0]); + + // Create some traffic. + incrementCurrentTime(MINUTE_IN_MILLIS); + expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1) + .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, + 49L, 71L, 72L, 48L, 0L))); + forcePollAndWaitForIdle(); + + // OEM_PAID + OEM_PRIVATE network comes online. + states = new NetworkState[]{buildOemManagedMobileState(IMSI_1, false, + new int[]{NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE, + NetworkCapabilities.NET_CAPABILITY_OEM_PAID})}; + expectNetworkStatsSummary(buildEmptyStats()); + expectNetworkStatsUidDetail(buildEmptyStats()); + mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states), + new UnderlyingNetworkInfo[0]); + + // Create some traffic. + incrementCurrentTime(MINUTE_IN_MILLIS); + expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1) + .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, + 57L, 86L, 83L, 93L, 0L))); + forcePollAndWaitForIdle(); + + // OEM_NONE network comes online. + states = new NetworkState[]{buildOemManagedMobileState(IMSI_1, false, new int[]{})}; + expectNetworkStatsSummary(buildEmptyStats()); + expectNetworkStatsUidDetail(buildEmptyStats()); + mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states), + new UnderlyingNetworkInfo[0]); + + // Create some traffic. + incrementCurrentTime(MINUTE_IN_MILLIS); + expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1) + .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, + 29L, 73L, 34L, 31L, 0L))); + forcePollAndWaitForIdle(); + + // Verify OEM_PAID template gets only relevant stats. + assertUidTotal(templateOemPaid, UID_RED, 36L, 41L, 24L, 96L, 0); + + // Verify OEM_PRIVATE template gets only relevant stats. + assertUidTotal(templateOemPrivate, UID_RED, 49L, 71L, 72L, 48L, 0); + + // Verify OEM_PAID + OEM_PRIVATE template gets only relevant stats. + assertUidTotal(templateOemAll, UID_RED, 57L, 86L, 83L, 93L, 0); + + // Verify OEM_NONE sees only non-OEM managed stats. + assertUidTotal(templateOemNone, UID_RED, 29L, 73L, 34L, 31L, 0); + + // Verify OEM_MANAGED_YES sees all OEM managed stats. + assertUidTotal(templateOemYes, UID_RED, + 36L + 49L + 57L, + 41L + 71L + 86L, + 24L + 72L + 83L, + 96L + 48L + 93L, 0); + + // Verify ALL_MOBILE template gets both OEM managed and non-OEM managed stats. + assertUidTotal(sTemplateImsi1, UID_RED, + 36L + 49L + 57L + 29L, + 41L + 71L + 86L + 73L, + 24L + 72L + 83L + 34L, + 96L + 48L + 93L + 31L, 0); + } + // TODO: support per IMSI state private void setMobileRatTypeAndWaitForIdle(int ratType) { when(mNetworkStatsSubscriptionsMonitor.getRatTypeForSubscriberId(anyString())) @@ -1488,6 +1604,20 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { return new NetworkState(TYPE_VPN, prop, new NetworkCapabilities(), VPN_NETWORK, null); } + private static NetworkState buildOemManagedMobileState(String subscriberId, boolean isRoaming, + int[] oemNetCapabilities) { + final LinkProperties prop = new LinkProperties(); + prop.setInterfaceName(TEST_IFACE); + final NetworkCapabilities capabilities = new NetworkCapabilities(); + capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED, false); + capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, !isRoaming); + for (int nc : oemNetCapabilities) { + capabilities.setCapability(nc, true); + } + capabilities.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR); + return new NetworkState(TYPE_MOBILE, prop, capabilities, MOBILE_NETWORK, subscriberId); + } + private long getElapsedRealtime() { return mElapsedRealtime; } |