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

Commit fd1cd4e2 authored by Hakjun Choi's avatar Hakjun Choi
Browse files

Normalization of duration related components for RCS single registration

metrics

There is currently an issue where IMS SR metrics can have durations greater than 24 hrs in some cases.
In these cases, this can mess up aggregation on the server side.
For consistency, we should also do the same normalization for single
registration metrics

Bug: 230913721
Test: aTest PersistAtosStorageTest
Change-Id: I4e67e9ec3bb1dad87046632e390f26a27408b8cd
parent ff73fcc7
Loading
Loading
Loading
Loading
+54 −14
Original line number Diff line number Diff line
@@ -866,14 +866,15 @@ public class PersistAtomsStorage {
    }

    /**
     * Returns and clears the ImsRegistrationFeatureTagStats if last pulled longer than {@code
     * minIntervalMillis} ago, otherwise returns {@code null}.
     * Returns and clears the ImsRegistrationFeatureTagStats if last pulled longer than
     * {@code minIntervalMillis} ago, otherwise returns {@code null}.
     */
    @Nullable
    public synchronized ImsRegistrationFeatureTagStats[] getImsRegistrationFeatureTagStats(
            long minIntervalMillis) {
        if (getWallTimeMillis() - mAtoms.imsRegistrationFeatureTagStatsPullTimestampMillis
                > minIntervalMillis) {
        long intervalMillis =
                getWallTimeMillis() - mAtoms.rcsAcsProvisioningStatsPullTimestampMillis;
        if (intervalMillis > minIntervalMillis) {
            mAtoms.imsRegistrationFeatureTagStatsPullTimestampMillis = getWallTimeMillis();
            ImsRegistrationFeatureTagStats[] previousStats =
                    mAtoms.imsRegistrationFeatureTagStats;
@@ -905,16 +906,26 @@ public class PersistAtomsStorage {
    }

    /**
     * Returns and clears the RcsAcsProvisioningStats if last pulled longer than {@code
     * minIntervalMillis} ago, otherwise returns {@code null}.
     * Returns and clears the RcsAcsProvisioningStats normalized to 24h cycle if last pulled
     * longer than {@code minIntervalMillis} ago, otherwise returns {@code null}.
     */
    @Nullable
    public synchronized RcsAcsProvisioningStats[] getRcsAcsProvisioningStats(
            long minIntervalMillis) {
        if (getWallTimeMillis() - mAtoms.rcsAcsProvisioningStatsPullTimestampMillis
                > minIntervalMillis) {
        long intervalMillis =
                getWallTimeMillis() - mAtoms.rcsAcsProvisioningStatsPullTimestampMillis;
        if (intervalMillis > minIntervalMillis) {
            mAtoms.rcsAcsProvisioningStatsPullTimestampMillis = getWallTimeMillis();
            RcsAcsProvisioningStats[] previousStats = mAtoms.rcsAcsProvisioningStats;

            for (RcsAcsProvisioningStats stat: previousStats) {
                // in case pull interval is greater than 24H, normalize it as of one day interval
                if (intervalMillis > DAY_IN_MILLIS) {
                    stat.stateTimerMillis = normalizeDurationTo24H(stat.stateTimerMillis,
                            intervalMillis);
                }
            }

            mAtoms.rcsAcsProvisioningStats = new RcsAcsProvisioningStats[0];
            saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_GET_MILLIS);
            return previousStats;
@@ -929,10 +940,19 @@ public class PersistAtomsStorage {
     */
    @Nullable
    public synchronized SipDelegateStats[] getSipDelegateStats(long minIntervalMillis) {
        if (getWallTimeMillis() - mAtoms.sipDelegateStatsPullTimestampMillis
                > minIntervalMillis) {
        long intervalMillis = getWallTimeMillis() - mAtoms.sipDelegateStatsPullTimestampMillis;
        if (intervalMillis > minIntervalMillis) {
            mAtoms.sipDelegateStatsPullTimestampMillis = getWallTimeMillis();
            SipDelegateStats[] previousStats = mAtoms.sipDelegateStats;

            for (SipDelegateStats stat: previousStats) {
                // in case pull interval is greater than 24H, normalize it as of one day interval
                if (intervalMillis > DAY_IN_MILLIS) {
                    stat.uptimeMillis = normalizeDurationTo24H(stat.uptimeMillis,
                            intervalMillis);
                }
            }

            mAtoms.sipDelegateStats = new SipDelegateStats[0];
            saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_GET_MILLIS);
            return previousStats;
@@ -948,10 +968,20 @@ public class PersistAtomsStorage {
    @Nullable
    public synchronized SipTransportFeatureTagStats[] getSipTransportFeatureTagStats(
            long minIntervalMillis) {
        if (getWallTimeMillis() - mAtoms.sipTransportFeatureTagStatsPullTimestampMillis
                > minIntervalMillis) {
        long intervalMillis =
                getWallTimeMillis() - mAtoms.sipTransportFeatureTagStatsPullTimestampMillis;
        if (intervalMillis > minIntervalMillis) {
            mAtoms.sipTransportFeatureTagStatsPullTimestampMillis = getWallTimeMillis();
            SipTransportFeatureTagStats[] previousStats = mAtoms.sipTransportFeatureTagStats;

            for (SipTransportFeatureTagStats stat: previousStats) {
                // in case pull interval is greater than 24H, normalize it as of one day interval
                if (intervalMillis > DAY_IN_MILLIS) {
                    stat.associatedMillis = normalizeDurationTo24H(stat.associatedMillis,
                            intervalMillis);
                }
            }

            mAtoms.sipTransportFeatureTagStats = new SipTransportFeatureTagStats[0];
            saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_GET_MILLIS);
            return previousStats;
@@ -1045,11 +1075,21 @@ public class PersistAtomsStorage {
    @Nullable
    public synchronized ImsRegistrationServiceDescStats[] getImsRegistrationServiceDescStats(long
            minIntervalMillis) {
        if (getWallTimeMillis() - mAtoms.imsRegistrationServiceDescStatsPullTimestampMillis
                > minIntervalMillis) {
        long intervalMillis =
                getWallTimeMillis() - mAtoms.imsRegistrationServiceDescStatsPullTimestampMillis;
        if (intervalMillis > minIntervalMillis) {
            mAtoms.imsRegistrationServiceDescStatsPullTimestampMillis = getWallTimeMillis();
            ImsRegistrationServiceDescStats[] previousStats =
                mAtoms.imsRegistrationServiceDescStats;

            for (ImsRegistrationServiceDescStats stat: previousStats) {
                // in case pull interval is greater than 24H, normalize it as of one day interval
                if (intervalMillis > DAY_IN_MILLIS) {
                    stat.publishedMillis = normalizeDurationTo24H(stat.publishedMillis,
                            intervalMillis);
                }
            }

            mAtoms.imsRegistrationServiceDescStats = new ImsRegistrationServiceDescStats[0];
            saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_GET_MILLIS);
            return previousStats;
+132 −10
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.internal.telephony.metrics;
import static android.telephony.TelephonyManager.NETWORK_TYPE_BITMASK_GPRS;
import static android.telephony.TelephonyManager.NETWORK_TYPE_BITMASK_GSM;
import static android.text.format.DateUtils.DAY_IN_MILLIS;
import static android.text.format.DateUtils.HOUR_IN_MILLIS;

import static com.android.internal.telephony.TelephonyStatsLog.GBA_EVENT__FAILED_REASON__FEATURE_NOT_READY;
import static com.android.internal.telephony.TelephonyStatsLog.GBA_EVENT__FAILED_REASON__UNKNOWN;
@@ -2105,13 +2106,16 @@ public class PersistAtomsStorageTest extends TelephonyTest {
    @Test
    @SmallTest
    public void addRcsAcsProvisioningStats_updateExistingEntries() throws Exception {
        final int maxCount = 5;
        final long duration = START_TIME_MILLIS;
        createEmptyTestFile();

        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);

        // store 5 same atoms (1Proto), but only 1 atoms stored with count 5, total time 2000L * 5
        // store 5 same atoms (2Proto), but only 1 atoms stored with count 5, total time 2000L * 5
        for (int i = 0; i < 5; i++) {

        for (int i = 0; i < maxCount; i++) {
            mPersistAtomsStorage
                    .addRcsAcsProvisioningStats(copyOf(mRcsAcsProvisioningStats1Proto));
            mPersistAtomsStorage.incTimeMillis(100L);
@@ -2122,6 +2126,7 @@ public class PersistAtomsStorageTest extends TelephonyTest {
        // add one more atoms (2Proto), count 6, total time 2000L * 6
        mPersistAtomsStorage
                .addRcsAcsProvisioningStats(copyOf(mRcsAcsProvisioningStats2Proto));
        mPersistAtomsStorage.incTimeMillis(100L);

        verifyCurrentStateSavedToFileOnce();

@@ -2129,9 +2134,11 @@ public class PersistAtomsStorageTest extends TelephonyTest {
                mPersistAtomsStorage.getRcsAcsProvisioningStats(0L);

        // atom (1Proto) : count = 5, time = 2000L * 5
        assertHasStatsAndCountDuration(result, mRcsAcsProvisioningStats1Proto, 5, 2000L * 5);
        assertHasStatsAndCountDuration(
                result, mRcsAcsProvisioningStats1Proto, 5, duration * maxCount);
        // atom (2Proto) : count = 6, time = 2000L * 6
        assertHasStatsAndCountDuration(result, mRcsAcsProvisioningStats2Proto, 6, 2000L * 6);
        assertHasStatsAndCountDuration(
                result, mRcsAcsProvisioningStats2Proto, 6, duration * (maxCount + 1));
    }

    @Test
@@ -2154,27 +2161,27 @@ public class PersistAtomsStorageTest extends TelephonyTest {
        createTestFile(START_TIME_MILLIS);

        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
        mPersistAtomsStorage.incTimeMillis(100L);
        mPersistAtomsStorage.incTimeMillis(DAY_IN_MILLIS);
        RcsAcsProvisioningStats[] statses1 =
                mPersistAtomsStorage.getRcsAcsProvisioningStats(50L);
        mPersistAtomsStorage.incTimeMillis(100L);
                mPersistAtomsStorage.getRcsAcsProvisioningStats(DAY_IN_MILLIS - HOUR_IN_MILLIS);
        mPersistAtomsStorage.incTimeMillis(DAY_IN_MILLIS);
        RcsAcsProvisioningStats[] statses2 =
                mPersistAtomsStorage.getRcsAcsProvisioningStats(50L);
                mPersistAtomsStorage.getRcsAcsProvisioningStats(DAY_IN_MILLIS - HOUR_IN_MILLIS);

        // first results of get should have two atoms, second should be empty
        // pull timestamp should be updated and saved
        assertProtoArrayEqualsIgnoringOrder(mRcsAcsProvisioningStatses, statses1);
        assertProtoArrayEquals(new RcsAcsProvisioningStats[0], statses2);
        assertEquals(
                START_TIME_MILLIS + 200L,
                START_TIME_MILLIS + 2 * DAY_IN_MILLIS,
                mPersistAtomsStorage.getAtomsProto()
                        .rcsAcsProvisioningStatsPullTimestampMillis);
        InOrder inOrder = inOrder(mTestFileOutputStream);
        assertEquals(
                START_TIME_MILLIS + 100L,
                START_TIME_MILLIS + DAY_IN_MILLIS,
                getAtomsWritten(inOrder).rcsAcsProvisioningStatsPullTimestampMillis);
        assertEquals(
                START_TIME_MILLIS + 200L,
                START_TIME_MILLIS + 2 * DAY_IN_MILLIS,
                getAtomsWritten(inOrder).rcsAcsProvisioningStatsPullTimestampMillis);
        inOrder.verifyNoMoreInteractions();
    }
@@ -2317,6 +2324,121 @@ public class PersistAtomsStorageTest extends TelephonyTest {
                serviceStates);
    }

    @Test
    public void getRcsAcsProvisioningStats_24h_normalization() throws Exception {
        // in case pulling interval is greater than a day
        final long stateTimer = HOUR_IN_MILLIS;
        final long weightFactor = 2;
        createTestFile(START_TIME_MILLIS);
        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
        RcsAcsProvisioningStats mSubjectStats = copyOf(mRcsAcsProvisioningStats1Proto);

        mSubjectStats.stateTimerMillis = stateTimer;
        mPersistAtomsStorage.addRcsAcsProvisioningStats(mSubjectStats);
        mPersistAtomsStorage.incTimeMillis(DAY_IN_MILLIS * weightFactor);

        RcsAcsProvisioningStats[] savedStats =
                mPersistAtomsStorage.getRcsAcsProvisioningStats(0L);

        assertEquals(
                (START_TIME_MILLIS + stateTimer) / weightFactor, savedStats[0].stateTimerMillis);

        // in case pulling interval is smaller than a day
        long incTimeMillis = DAY_IN_MILLIS * 23 / 24 + 1;
        mSubjectStats = copyOf(mRcsAcsProvisioningStats1Proto);
        mSubjectStats.stateTimerMillis = stateTimer;
        mPersistAtomsStorage.addRcsAcsProvisioningStats(mSubjectStats);
        mPersistAtomsStorage.incTimeMillis(incTimeMillis);
        savedStats =
                mPersistAtomsStorage.getRcsAcsProvisioningStats(0L);


        assertEquals(stateTimer, savedStats[0].stateTimerMillis);
    }

    @Test
    public void getSipDelegateStats_24h_normalization() throws Exception {
        final long stateTimer = HOUR_IN_MILLIS;
        final long weightFactor = 2;
        createTestFile(START_TIME_MILLIS);
        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
        SipDelegateStats mSubjectStats = copyOf(mSipDelegateStats1);
        mSubjectStats.uptimeMillis = stateTimer;
        mPersistAtomsStorage.addSipDelegateStats(mSubjectStats);
        mPersistAtomsStorage.incTimeMillis(DAY_IN_MILLIS * weightFactor);
        SipDelegateStats[] savedStats =
                mPersistAtomsStorage.getSipDelegateStats(0L);
        for (SipDelegateStats stat : savedStats) {
            if (stat.destroyReason
                    == SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP) {
                assertEquals(stateTimer / weightFactor, stat.uptimeMillis);
            }
        }

        long incTimeMillis = DAY_IN_MILLIS * 23 / 24 + 1;
        mSubjectStats = copyOf(mSipDelegateStats1);
        mSubjectStats.uptimeMillis = stateTimer;
        mPersistAtomsStorage.addSipDelegateStats(mSubjectStats);
        mPersistAtomsStorage.incTimeMillis(incTimeMillis);
        savedStats =
                mPersistAtomsStorage.getSipDelegateStats(0L);
        for (SipDelegateStats stat : savedStats) {
            if (stat.destroyReason
                    == SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP) {
                assertEquals(stateTimer, stat.uptimeMillis);
            }
        }
    }

    @Test
    public void getSipTransportFeatureTagStats_24h_normalization() throws Exception {
        final long stateTimer = HOUR_IN_MILLIS;
        final long weightFactor = 2;
        createTestFile(START_TIME_MILLIS);
        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
        SipTransportFeatureTagStats mSubjectStats = copyOf(mSipTransportFeatureTagStats1);
        mSubjectStats.associatedMillis = stateTimer;
        mPersistAtomsStorage.addSipTransportFeatureTagStats(mSubjectStats);
        mPersistAtomsStorage.incTimeMillis(DAY_IN_MILLIS * weightFactor);
        SipTransportFeatureTagStats[] savedStats =
                mPersistAtomsStorage.getSipTransportFeatureTagStats(0L);
        assertEquals((stateTimer) / weightFactor, savedStats[0].associatedMillis);

        long incTimeMillis = DAY_IN_MILLIS * 23 / 24 + 1;
        mSubjectStats = copyOf(mSipTransportFeatureTagStats1);
        mSubjectStats.associatedMillis = stateTimer;
        mPersistAtomsStorage.addSipTransportFeatureTagStats(mSubjectStats);
        mPersistAtomsStorage.incTimeMillis(incTimeMillis);
        savedStats =
                mPersistAtomsStorage.getSipTransportFeatureTagStats(0L);
        assertEquals(stateTimer, savedStats[0].associatedMillis);
    }

    @Test
    public void getImsRegistrationServiceDescStats_24h_normalization() throws Exception {
        final long stateTimer = HOUR_IN_MILLIS;
        final long weightFactor = 2;
        createTestFile(START_TIME_MILLIS);
        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
        ImsRegistrationServiceDescStats mSubjectStats = copyOf(mImsRegistrationServiceIm);
        mSubjectStats.publishedMillis = stateTimer;
        mPersistAtomsStorage.addImsRegistrationServiceDescStats(mSubjectStats);
        mPersistAtomsStorage.incTimeMillis(DAY_IN_MILLIS * weightFactor);
        ImsRegistrationServiceDescStats[] savedStats =
                mPersistAtomsStorage.getImsRegistrationServiceDescStats(0L);
        assertEquals(
                (START_TIME_MILLIS + stateTimer) / weightFactor, savedStats[0].publishedMillis);

        long incTimeMillis = DAY_IN_MILLIS * 23 / 24 + 1;
        mSubjectStats = copyOf(mImsRegistrationServiceIm);
        mSubjectStats.publishedMillis = stateTimer;
        mPersistAtomsStorage.addImsRegistrationServiceDescStats(mSubjectStats);
        mPersistAtomsStorage.incTimeMillis(incTimeMillis);
        savedStats =
                mPersistAtomsStorage.getImsRegistrationServiceDescStats(0L);
        assertEquals(stateTimer, savedStats[0].publishedMillis);
    }

    @Test
    @SmallTest
    public void addImsDedicatedBearerListenerEvent_emptyProto() throws Exception {