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

Commit 2d4fa2c0 authored by junyulai's avatar junyulai
Browse files

[SM05] Enable record mobile network stats by collapsed rat type

Switch on the recording in device side. Metrics will be
collected in follow-up patches which can be independently
enabled/disabled.

This change also fix the fail in NetworkStatsCollectionTest
which caused by enabling this feature, where the rounding
problem happened when records are distributed into smaller
buckets and categorized into more NetworkIdentity.

Test: atest FrameworksNetTests
Bug: 129082217
Change-Id: If330e85330a4ff713dd420c98d42fa741eabd90a
parent e19045cc
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -45,7 +45,7 @@ public class NetworkIdentity implements Comparable<NetworkIdentity> {
     * {@link #SUBTYPE_COMBINED}.
     */
    // TODO: make this flag configurable through settings. See http://b/146415925
    public static final boolean COMBINE_SUBTYPE_ENABLED = true;
    public static final boolean COMBINE_SUBTYPE_ENABLED = false;

    public static final int SUBTYPE_COMBINED = -1;

+2 −2
Original line number Diff line number Diff line
@@ -1209,7 +1209,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
            final int collapsedRatType = getCollapsedRatType(networkType);
            if (collapsedRatType == mLastCollapsedRatType) return;

            if (LOGV) {
            if (LOGD) {
                Log.d(TAG, "subtype changed for mobile: "
                        + mLastCollapsedRatType + " -> " + collapsedRatType);
            }
@@ -1217,7 +1217,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
            mHandler.removeMessages(MSG_UPDATE_IFACES);
            mLastCollapsedRatType = collapsedRatType;
            mHandler.sendMessageDelayed(
                    mHandler.obtainMessage(MSG_UPDATE_IFACES), SECOND_IN_MILLIS);
                    mHandler.obtainMessage(MSG_UPDATE_IFACES), mSettings.getPollDelay());
        }
    }

+45 −45
Original line number Diff line number Diff line
@@ -319,33 +319,33 @@ public class NetworkStatsCollectionTest {
            assertEntry(18322, 75, 15031, 75, history.getValues(i++, null));
            assertEntry(527798, 761, 78570, 652, history.getValues(i++, null));
            assertEntry(527797, 760, 78570, 651, history.getValues(i++, null));
            assertEntry(10747, 50, 16838, 55, history.getValues(i++, null));
            assertEntry(10747, 49, 16838, 54, history.getValues(i++, null));
            assertEntry(10747, 50, 16839, 55, history.getValues(i++, null));
            assertEntry(10747, 49, 16837, 54, history.getValues(i++, null));
            assertEntry(89191, 151, 18021, 140, history.getValues(i++, null));
            assertEntry(89190, 150, 18020, 139, history.getValues(i++, null));
            assertEntry(3821, 22, 4525, 26, history.getValues(i++, null));
            assertEntry(3820, 22, 4524, 26, history.getValues(i++, null));
            assertEntry(91686, 159, 18575, 146, history.getValues(i++, null));
            assertEntry(91685, 159, 18575, 146, history.getValues(i++, null));
            assertEntry(8289, 35, 6863, 38, history.getValues(i++, null));
            assertEntry(8289, 35, 6863, 38, history.getValues(i++, null));
            assertEntry(3821, 23, 4525, 26, history.getValues(i++, null));
            assertEntry(3820, 21, 4524, 26, history.getValues(i++, null));
            assertEntry(91686, 159, 18576, 146, history.getValues(i++, null));
            assertEntry(91685, 159, 18574, 146, history.getValues(i++, null));
            assertEntry(8289, 36, 6864, 39, history.getValues(i++, null));
            assertEntry(8289, 34, 6862, 37, history.getValues(i++, null));
            assertEntry(113914, 174, 18364, 157, history.getValues(i++, null));
            assertEntry(113913, 173, 18364, 157, history.getValues(i++, null));
            assertEntry(11378, 49, 9261, 49, history.getValues(i++, null));
            assertEntry(11377, 48, 9261, 49, history.getValues(i++, null));
            assertEntry(201765, 328, 41808, 291, history.getValues(i++, null));
            assertEntry(201765, 328, 41807, 290, history.getValues(i++, null));
            assertEntry(106106, 218, 39917, 201, history.getValues(i++, null));
            assertEntry(106105, 217, 39917, 201, history.getValues(i++, null));
            assertEntry(11378, 49, 9261, 50, history.getValues(i++, null));
            assertEntry(11377, 48, 9261, 48, history.getValues(i++, null));
            assertEntry(201766, 328, 41808, 291, history.getValues(i++, null));
            assertEntry(201764, 328, 41807, 290, history.getValues(i++, null));
            assertEntry(106106, 219, 39918, 202, history.getValues(i++, null));
            assertEntry(106105, 216, 39916, 200, history.getValues(i++, null));
            assertEquals(history.size(), i);

            // Slice from middle should be untouched
            history = getHistory(collection, plan, TIME_B - HOUR_IN_MILLIS,
                    TIME_B + HOUR_IN_MILLIS); i = 0;
            assertEntry(3821, 22, 4525, 26, history.getValues(i++, null));
            assertEntry(3820, 22, 4524, 26, history.getValues(i++, null));
            assertEntry(91686, 159, 18575, 146, history.getValues(i++, null));
            assertEntry(91685, 159, 18575, 146, history.getValues(i++, null));
            assertEntry(3821, 23, 4525, 26, history.getValues(i++, null));
            assertEntry(3820, 21, 4524, 26, history.getValues(i++, null));
            assertEntry(91686, 159, 18576, 146, history.getValues(i++, null));
            assertEntry(91685, 159, 18574, 146, history.getValues(i++, null));
            assertEquals(history.size(), i);
        }

@@ -373,25 +373,25 @@ public class NetworkStatsCollectionTest {
            assertEntry(527797, 760, 78570, 651, history.getValues(i++, null));
            // Cycle point; start data normalization
            assertEntry(7507, 0, 11763, 0, history.getValues(i++, null));
            assertEntry(7507, 0, 11763, 0, history.getValues(i++, null));
            assertEntry(7507, 0, 11762, 0, history.getValues(i++, null));
            assertEntry(62309, 0, 12589, 0, history.getValues(i++, null));
            assertEntry(62309, 0, 12588, 0, history.getValues(i++, null));
            assertEntry(2669, 0, 3161, 0, history.getValues(i++, null));
            assertEntry(2668, 0, 3160, 0, history.getValues(i++, null));
            // Anchor point; end data normalization
            assertEntry(91686, 159, 18575, 146, history.getValues(i++, null));
            assertEntry(91685, 159, 18575, 146, history.getValues(i++, null));
            assertEntry(8289, 35, 6863, 38, history.getValues(i++, null));
            assertEntry(8289, 35, 6863, 38, history.getValues(i++, null));
            assertEntry(91686, 159, 18576, 146, history.getValues(i++, null));
            assertEntry(91685, 159, 18574, 146, history.getValues(i++, null));
            assertEntry(8289, 36, 6864, 39, history.getValues(i++, null));
            assertEntry(8289, 34, 6862, 37, history.getValues(i++, null));
            assertEntry(113914, 174, 18364, 157, history.getValues(i++, null));
            assertEntry(113913, 173, 18364, 157, history.getValues(i++, null));
            // Cycle point
            assertEntry(11378, 49, 9261, 49, history.getValues(i++, null));
            assertEntry(11377, 48, 9261, 49, history.getValues(i++, null));
            assertEntry(201765, 328, 41808, 291, history.getValues(i++, null));
            assertEntry(201765, 328, 41807, 290, history.getValues(i++, null));
            assertEntry(106106, 218, 39917, 201, history.getValues(i++, null));
            assertEntry(106105, 217, 39917, 201, history.getValues(i++, null));
            assertEntry(11378, 49, 9261, 50, history.getValues(i++, null));
            assertEntry(11377, 48, 9261, 48, history.getValues(i++, null));
            assertEntry(201766, 328, 41808, 291, history.getValues(i++, null));
            assertEntry(201764, 328, 41807, 290, history.getValues(i++, null));
            assertEntry(106106, 219, 39918, 202, history.getValues(i++, null));
            assertEntry(106105, 216, 39916, 200, history.getValues(i++, null));
            assertEquals(history.size(), i);

            // Slice from middle should be augmented
@@ -399,8 +399,8 @@ public class NetworkStatsCollectionTest {
                    TIME_B + HOUR_IN_MILLIS); i = 0;
            assertEntry(2669, 0, 3161, 0, history.getValues(i++, null));
            assertEntry(2668, 0, 3160, 0, history.getValues(i++, null));
            assertEntry(91686, 159, 18575, 146, history.getValues(i++, null));
            assertEntry(91685, 159, 18575, 146, history.getValues(i++, null));
            assertEntry(91686, 159, 18576, 146, history.getValues(i++, null));
            assertEntry(91685, 159, 18574, 146, history.getValues(i++, null));
            assertEquals(history.size(), i);
        }

@@ -427,34 +427,34 @@ public class NetworkStatsCollectionTest {
            assertEntry(527798, 761, 78570, 652, history.getValues(i++, null));
            assertEntry(527797, 760, 78570, 651, history.getValues(i++, null));
            // Cycle point; start data normalization
            assertEntry(15015, 0, 23526, 0, history.getValues(i++, null));
            assertEntry(15015, 0, 23526, 0, history.getValues(i++, null));
            assertEntry(15015, 0, 23527, 0, history.getValues(i++, null));
            assertEntry(15015, 0, 23524, 0, history.getValues(i++, null));
            assertEntry(124619, 0, 25179, 0, history.getValues(i++, null));
            assertEntry(124618, 0, 25177, 0, history.getValues(i++, null));
            assertEntry(5338, 0, 6322, 0, history.getValues(i++, null));
            assertEntry(5337, 0, 6320, 0, history.getValues(i++, null));
            // Anchor point; end data normalization
            assertEntry(91686, 159, 18575, 146, history.getValues(i++, null));
            assertEntry(91685, 159, 18575, 146, history.getValues(i++, null));
            assertEntry(8289, 35, 6863, 38, history.getValues(i++, null));
            assertEntry(8289, 35, 6863, 38, history.getValues(i++, null));
            assertEntry(91686, 159, 18576, 146, history.getValues(i++, null));
            assertEntry(91685, 159, 18574, 146, history.getValues(i++, null));
            assertEntry(8289, 36, 6864, 39, history.getValues(i++, null));
            assertEntry(8289, 34, 6862, 37, history.getValues(i++, null));
            assertEntry(113914, 174, 18364, 157, history.getValues(i++, null));
            assertEntry(113913, 173, 18364, 157, history.getValues(i++, null));
            // Cycle point
            assertEntry(11378, 49, 9261, 49, history.getValues(i++, null));
            assertEntry(11377, 48, 9261, 49, history.getValues(i++, null));
            assertEntry(201765, 328, 41808, 291, history.getValues(i++, null));
            assertEntry(201765, 328, 41807, 290, history.getValues(i++, null));
            assertEntry(106106, 218, 39917, 201, history.getValues(i++, null));
            assertEntry(106105, 217, 39917, 201, history.getValues(i++, null));
            assertEntry(11378, 49, 9261, 50, history.getValues(i++, null));
            assertEntry(11377, 48, 9261, 48, history.getValues(i++, null));
            assertEntry(201766, 328, 41808, 291, history.getValues(i++, null));
            assertEntry(201764, 328, 41807, 290, history.getValues(i++, null));
            assertEntry(106106, 219, 39918, 202, history.getValues(i++, null));
            assertEntry(106105, 216, 39916, 200, history.getValues(i++, null));

            // Slice from middle should be augmented
            history = getHistory(collection, plan, TIME_B - HOUR_IN_MILLIS,
                    TIME_B + HOUR_IN_MILLIS); i = 0;
            assertEntry(5338, 0, 6322, 0, history.getValues(i++, null));
            assertEntry(5337, 0, 6320, 0, history.getValues(i++, null));
            assertEntry(91686, 159, 18575, 146, history.getValues(i++, null));
            assertEntry(91685, 159, 18575, 146, history.getValues(i++, null));
            assertEntry(91686, 159, 18576, 146, history.getValues(i++, null));
            assertEntry(91685, 159, 18574, 146, history.getValues(i++, null));
            assertEquals(history.size(), i);
        }
    }
+104 −5
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@ 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.buildTemplateMobileAll;
import static android.net.NetworkTemplate.buildTemplateMobileWithRatType;
import static android.net.NetworkTemplate.buildTemplateWifiWildcard;
import static android.net.TrafficStats.MB_IN_BYTES;
import static android.net.TrafficStats.UID_REMOVED;
@@ -60,11 +61,13 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.AlarmManager;
import android.app.usage.NetworkStatsManager;
import android.content.Context;
@@ -92,6 +95,8 @@ import android.os.Message;
import android.os.Messenger;
import android.os.PowerManager;
import android.os.SimpleClock;
import android.telephony.PhoneStateListener;
import android.telephony.ServiceState;
import android.telephony.TelephonyManager;

import androidx.test.InstrumentationRegistry;
@@ -163,11 +168,14 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
    private @Mock NetworkStatsSettings mSettings;
    private @Mock IBinder mBinder;
    private @Mock AlarmManager mAlarmManager;
    private @Mock TelephonyManager mTelephonyManager;
    private HandlerThread mHandlerThread;

    private NetworkStatsService mService;
    private INetworkStatsSession mSession;
    private INetworkManagementEventObserver mNetworkObserver;
    @Nullable
    private PhoneStateListener mPhoneStateListener;

    private final Clock mClock = new SimpleClock(ZoneOffset.UTC) {
        @Override
@@ -195,7 +203,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
        mHandlerThread = new HandlerThread("HandlerThread");
        final NetworkStatsService.Dependencies deps = makeDependencies();
        mService = new NetworkStatsService(mServiceContext, mNetManager, mAlarmManager, wakeLock,
                mClock, mServiceContext.getSystemService(TelephonyManager.class), mSettings,
                mClock, mTelephonyManager, mSettings,
                mStatsFactory, new NetworkStatsObservers(), mStatsDir, getBaseDir(mStatsDir), deps);

        mElapsedRealtime = 0L;
@@ -216,6 +224,12 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
                ArgumentCaptor.forClass(INetworkManagementEventObserver.class);
        verify(mNetManager).registerObserver(networkObserver.capture());
        mNetworkObserver = networkObserver.getValue();

        // Capture the phone state listener that created by service.
        final ArgumentCaptor<PhoneStateListener> phoneStateListenerCaptor =
                ArgumentCaptor.forClass(PhoneStateListener.class);
        verify(mTelephonyManager).listen(phoneStateListenerCaptor.capture(), anyInt());
        mPhoneStateListener = phoneStateListenerCaptor.getValue();
    }

    @NonNull
@@ -534,7 +548,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
    }

    @Test
    public void testUid3g4gCombinedByTemplate() throws Exception {
    public void testUid3gWimaxCombinedByTemplate() throws Exception {
        // pretend that network comes online
        expectDefaultSettings();
        NetworkState[] states = new NetworkState[] {buildMobile3gState(IMSI_1)};
@@ -558,10 +572,10 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
        assertUidTotal(sTemplateImsi1, UID_RED, 1024L, 8L, 1024L, 8L, 5);


        // now switch over to 4g network
        // now switch over to wimax network
        incrementCurrentTime(HOUR_IN_MILLIS);
        expectDefaultSettings();
        states = new NetworkState[] {buildMobile4gState(TEST_IFACE2)};
        states = new NetworkState[] {buildWimaxState(TEST_IFACE2)};
        expectNetworkStatsSummary(buildEmptyStats());
        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 0L)
@@ -588,6 +602,89 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
        assertUidTotal(sTemplateImsi1, UID_RED, 1536L, 12L, 1280L, 10L, 10);
    }

    @Test
    public void testMobileStatsByRatType() throws Exception {
        final NetworkTemplate template3g =
                buildTemplateMobileWithRatType(null, TelephonyManager.NETWORK_TYPE_UMTS);
        final NetworkTemplate template4g =
                buildTemplateMobileWithRatType(null, TelephonyManager.NETWORK_TYPE_LTE);
        final NetworkTemplate template5g =
                buildTemplateMobileWithRatType(null, TelephonyManager.NETWORK_TYPE_NR);
        final NetworkState[] states = new NetworkState[]{buildMobile3gState(IMSI_1)};

        // 3G network comes online.
        expectNetworkStatsSummary(buildEmptyStats());
        expectNetworkStatsUidDetail(buildEmptyStats());

        setMobileRatTypeAndWaitForIdle(TelephonyManager.NETWORK_TYPE_UMTS);
        mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states),
                new VpnInfo[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,
                        12L, 18L, 14L, 1L, 0L)));
        forcePollAndWaitForIdle();

        // Verify 3g templates gets stats.
        assertUidTotal(sTemplateImsi1, UID_RED, 12L, 18L, 14L, 1L, 0);
        assertUidTotal(template3g, UID_RED, 12L, 18L, 14L, 1L, 0);
        assertUidTotal(template4g, UID_RED, 0L, 0L, 0L, 0L, 0);
        assertUidTotal(template5g, UID_RED, 0L, 0L, 0L, 0L, 0);

        // 4G network comes online.
        incrementCurrentTime(MINUTE_IN_MILLIS);
        setMobileRatTypeAndWaitForIdle(TelephonyManager.NETWORK_TYPE_LTE);
        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
                // Append more traffic on existing 3g stats entry.
                .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE,
                        16L, 22L, 17L, 2L, 0L))
                // Add entry that is new on 4g.
                .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_FOREGROUND, TAG_NONE,
                        33L, 27L, 8L, 10L, 1L)));
        forcePollAndWaitForIdle();

        // Verify ALL_MOBILE template gets all. 3g template counters do not increase.
        assertUidTotal(sTemplateImsi1, UID_RED, 49L, 49L, 25L, 12L, 1);
        assertUidTotal(template3g, UID_RED, 12L, 18L, 14L, 1L, 0);
        // Verify 4g template counts appended stats on existing entry and newly created entry.
        assertUidTotal(template4g, UID_RED, 4L + 33L, 4L + 27L, 3L + 8L, 1L + 10L, 1);
        // Verify 5g template doesn't get anything since no traffic is generated on 5g.
        assertUidTotal(template5g, UID_RED, 0L, 0L, 0L, 0L, 0);

        // 5g network comes online.
        incrementCurrentTime(MINUTE_IN_MILLIS);
        setMobileRatTypeAndWaitForIdle(TelephonyManager.NETWORK_TYPE_NR);
        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
                // Existing stats remains.
                .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE,
                        16L, 22L, 17L, 2L, 0L))
                .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_FOREGROUND, TAG_NONE,
                        33L, 27L, 8L, 10L, 1L))
                // Add some traffic on 5g.
                .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE,
                5L, 13L, 31L, 9L, 2L)));
        forcePollAndWaitForIdle();

        // Verify ALL_MOBILE template gets all.
        assertUidTotal(sTemplateImsi1, UID_RED, 54L, 62L, 56L, 21L, 3);
        // 3g/4g template counters do not increase.
        assertUidTotal(template3g, UID_RED, 12L, 18L, 14L, 1L, 0);
        assertUidTotal(template4g, UID_RED, 4L + 33L, 4L + 27L, 3L + 8L, 1L + 10L, 1);
        // Verify 5g template gets the 5g count.
        assertUidTotal(template5g, UID_RED, 5L, 13L, 31L, 9L, 2);
    }

    // TODO: support per IMSI state
    private void setMobileRatTypeAndWaitForIdle(int ratType) {
        final ServiceState mockSs = mock(ServiceState.class);
        when(mockSs.getDataNetworkType()).thenReturn(ratType);
        mPhoneStateListener.onServiceStateChanged(mockSs);

        HandlerUtilsKt.waitForIdle(mHandlerThread, WAIT_TIMEOUT);
    }

    @Test
    public void testSummaryForAllUid() throws Exception {
        // pretend that network comes online
@@ -1242,6 +1339,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
        final NetworkCapabilities capabilities = new NetworkCapabilities();
        capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED, !isMetered);
        capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, true);
        capabilities.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
        return new NetworkState(info, prop, capabilities, WIFI_NETWORK, null, TEST_SSID);
    }

@@ -1259,10 +1357,11 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
        final NetworkCapabilities capabilities = new NetworkCapabilities();
        capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED, false);
        capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, !isRoaming);
        capabilities.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
        return new NetworkState(info, prop, capabilities, MOBILE_NETWORK, subscriberId, null);
    }

    private static NetworkState buildMobile4gState(String iface) {
    private static NetworkState buildWimaxState(@NonNull String iface) {
        final NetworkInfo info = new NetworkInfo(TYPE_WIMAX, 0, null, null);
        info.setDetailedState(DetailedState.CONNECTED, null, null);
        final LinkProperties prop = new LinkProperties();