Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7a02d32a authored by Chris Weir's avatar Chris Weir
Browse files

Update tests for PANS network usage metrics

Update existing tests to use new NetworkTemplate/NetworkIdentity
constructors, and add additional tests for new PANS metrics features.

Bug: 175793874
Bug: 174485293
Test: Run the tests in this CL with atest

Change-Id: I6f50993397d886a266874da0047c02022a69f62e
parent 6faddabe
Loading
Loading
Loading
Loading
+54 −0
Original line number Diff line number Diff line
/*
 * 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)
    }
}
+102 −5
Original line number Diff line number Diff line
@@ -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)
    }
}
+3 −2
Original line number Diff line number Diff line
@@ -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));

+2 −1
Original line number Diff line number Diff line
@@ -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;
    }

+130 −0
Original line number Diff line number Diff line
@@ -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;
    }