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

Commit 52bd4f13 authored by Yan Yan's avatar Yan Yan Committed by Gerrit Code Review
Browse files

Merge "VCN: Refactor getPacketLossRatePercentage to return an object" into main

parents 92e7cc4c 6b9f2df3
Loading
Loading
Loading
Loading
+97 −11
Original line number Diff line number Diff line
@@ -16,8 +16,10 @@

package com.android.server.vcn.routeselection;

import static com.android.internal.annotations.VisibleForTesting.Visibility;
import static com.android.server.vcn.util.PersistableBundleUtils.PersistableBundleWrapper;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.BroadcastReceiver;
@@ -38,6 +40,10 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.annotations.VisibleForTesting.Visibility;
import com.android.server.vcn.VcnContext;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.BitSet;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
@@ -56,8 +62,32 @@ import java.util.concurrent.TimeUnit;
public class IpSecPacketLossDetector extends NetworkMetricMonitor {
    private static final String TAG = IpSecPacketLossDetector.class.getSimpleName();

    @VisibleForTesting(visibility = Visibility.PRIVATE)
    static final int PACKET_LOSS_UNAVALAIBLE = -1;
    private static final int PACKET_LOSS_PERCENT_UNAVAILABLE = -1;

    @Retention(RetentionPolicy.SOURCE)
    @IntDef(
            prefix = {"PACKET_LOSS_"},
            value = {
                PACKET_LOSS_RATE_VALID,
                PACKET_LOSS_RATE_INVALID,
            })
    @Target({ElementType.TYPE_USE})
    private @interface PacketLossResultType {}

    /** Indicates a valid packet loss rate is available */
    private static final int PACKET_LOSS_RATE_VALID = 0;

    /**
     * Indicates that the detector cannot get a valid packet loss rate due to one of the following
     * reasons:
     *
     * <ul>
     *   <li>The replay window did not proceed and thus all packets might have been delivered out of
     *       order
     *   <li>There are unexpected errors
     * </ul>
     */
    private static final int PACKET_LOSS_RATE_INVALID = 1;

    // For VoIP, losses between 5% and 10% of the total packet stream will affect the quality
    // significantly (as per "Computer Networking for LANS to WANS: Hardware, Software and
@@ -307,24 +337,24 @@ public class IpSecPacketLossDetector extends NetworkMetricMonitor {
            return;
        }

        final int packetLossRate =
        final PacketLossCalculationResult calculateResult =
                mPacketLossCalculator.getPacketLossRatePercentage(
                        mLastIpSecTransformState, state, getLogPrefix());

        if (packetLossRate == PACKET_LOSS_UNAVALAIBLE) {
        if (calculateResult.getResultType() == PACKET_LOSS_RATE_INVALID) {
            return;
        }

        final String logMsg =
                "packetLossRate: "
                        + packetLossRate
                "calculateResult: "
                        + calculateResult
                        + "% in the past "
                        + (state.getTimestampMillis()
                                - mLastIpSecTransformState.getTimestampMillis())
                        + "ms";

        mLastIpSecTransformState = state;
        if (packetLossRate < mPacketLossRatePercentThreshold) {
        if (calculateResult.getPacketLossRatePercent() < mPacketLossRatePercentThreshold) {
            logV(logMsg);
            onValidationResultReceivedInternal(false /* isFailed */);
        } else {
@@ -343,7 +373,7 @@ public class IpSecPacketLossDetector extends NetworkMetricMonitor {
    @VisibleForTesting(visibility = Visibility.PRIVATE)
    public static class PacketLossCalculator {
        /** Calculate the packet loss rate between two timestamps */
        public int getPacketLossRatePercentage(
        public PacketLossCalculationResult getPacketLossRatePercentage(
                @NonNull IpSecTransformState oldState,
                @NonNull IpSecTransformState newState,
                String logPrefix) {
@@ -359,7 +389,7 @@ public class IpSecPacketLossDetector extends NetworkMetricMonitor {
            if (oldSeqHi == newSeqHi || newSeqHi < replayWindowSize) {
                // The replay window did not proceed and all packets might have been delivered out
                // of order
                return PACKET_LOSS_UNAVALAIBLE;
                return PacketLossCalculationResult.invalid();
            }

            // Get the expected packet count by assuming there is no packet loss. In this case, SA
@@ -386,10 +416,11 @@ public class IpSecPacketLossDetector extends NetworkMetricMonitor {
                    || actualPktCntDiff < 0
                    || actualPktCntDiff > expectedPktCntDiff) {
                logWtf(TAG, "Impossible values for expectedPktCntDiff or" + " actualPktCntDiff");
                return PACKET_LOSS_UNAVALAIBLE;
                return PacketLossCalculationResult.invalid();
            }

            return 100 - (int) (actualPktCntDiff * 100 / expectedPktCntDiff);
            final int percent = 100 - (int) (actualPktCntDiff * 100 / expectedPktCntDiff);
            return PacketLossCalculationResult.valid(percent);
        }
    }

@@ -409,4 +440,59 @@ public class IpSecPacketLossDetector extends NetworkMetricMonitor {
    private static long getPacketCntInReplayWindow(@NonNull IpSecTransformState state) {
        return BitSet.valueOf(state.getReplayBitmap()).cardinality();
    }

    @VisibleForTesting(visibility = Visibility.PRIVATE)
    public static class PacketLossCalculationResult {
        @PacketLossResultType private final int mResultType;
        private final int mPacketLossRatePercent;

        private PacketLossCalculationResult(@PacketLossResultType int type, int percent) {
            mResultType = type;
            mPacketLossRatePercent = percent;
        }

        /** Construct an instance that contains a valid packet loss rate */
        public static PacketLossCalculationResult valid(int percent) {
            return new PacketLossCalculationResult(PACKET_LOSS_RATE_VALID, percent);
        }

        /** Construct an instance indicating the inability to get a valid packet loss rate */
        public static PacketLossCalculationResult invalid() {
            return new PacketLossCalculationResult(
                    PACKET_LOSS_RATE_INVALID, PACKET_LOSS_PERCENT_UNAVAILABLE);
        }

        @PacketLossResultType
        public int getResultType() {
            return mResultType;
        }

        public int getPacketLossRatePercent() {
            return mPacketLossRatePercent;
        }

        @Override
        public int hashCode() {
            return Objects.hash(mResultType, mPacketLossRatePercent);
        }

        @Override
        public boolean equals(@Nullable Object other) {
            if (!(other instanceof PacketLossCalculationResult)) {
                return false;
            }

            final PacketLossCalculationResult rhs = (PacketLossCalculationResult) other;
            return mResultType == rhs.mResultType
                    && mPacketLossRatePercent == rhs.mPacketLossRatePercent;
        }

        @Override
        public String toString() {
            return "mResultType: "
                    + mResultType
                    + " | mPacketLossRatePercent: "
                    + mPacketLossRatePercent;
        }
    }
}
+32 −8
Original line number Diff line number Diff line
@@ -19,7 +19,6 @@ package com.android.server.vcn.routeselection;
import static android.net.vcn.VcnManager.VCN_NETWORK_SELECTION_IPSEC_PACKET_LOSS_PERCENT_THRESHOLD_KEY;
import static android.net.vcn.VcnManager.VCN_NETWORK_SELECTION_POLL_IPSEC_STATE_INTERVAL_SECONDS_KEY;

import static com.android.server.vcn.routeselection.IpSecPacketLossDetector.PACKET_LOSS_UNAVALAIBLE;
import static com.android.server.vcn.util.PersistableBundleUtils.PersistableBundleWrapper;

import static org.junit.Assert.assertEquals;
@@ -44,6 +43,7 @@ import android.net.IpSecTransformState;
import android.os.OutcomeReceiver;
import android.os.PowerManager;

import com.android.server.vcn.routeselection.IpSecPacketLossDetector.PacketLossCalculationResult;
import com.android.server.vcn.routeselection.IpSecPacketLossDetector.PacketLossCalculator;
import com.android.server.vcn.routeselection.NetworkMetricMonitor.IpSecTransformWrapper;
import com.android.server.vcn.routeselection.NetworkMetricMonitor.NetworkMetricMonitorCallback;
@@ -293,7 +293,9 @@ public class IpSecPacketLossDetectorTest extends NetworkEvaluationTestBase {
    }

    private void checkHandleLossRate(
            int mockPacketLossRate, boolean isLastStateExpectedToUpdate, boolean isCallbackExpected)
            PacketLossCalculationResult mockPacketLossRate,
            boolean isLastStateExpectedToUpdate,
            boolean isCallbackExpected)
            throws Exception {
        final OutcomeReceiver<IpSecTransformState, RuntimeException> xfrmStateReceiver =
                startMonitorAndCaptureStateReceiver();
@@ -327,26 +329,32 @@ public class IpSecPacketLossDetectorTest extends NetworkEvaluationTestBase {
    @Test
    public void testHandleLossRate_validationPass() throws Exception {
        checkHandleLossRate(
                2, true /* isLastStateExpectedToUpdate */, true /* isCallbackExpected */);
                PacketLossCalculationResult.valid(2),
                true /* isLastStateExpectedToUpdate */,
                true /* isCallbackExpected */);
    }

    @Test
    public void testHandleLossRate_validationFail() throws Exception {
        checkHandleLossRate(
                22, true /* isLastStateExpectedToUpdate */, true /* isCallbackExpected */);
                PacketLossCalculationResult.valid(22),
                true /* isLastStateExpectedToUpdate */,
                true /* isCallbackExpected */);
        verify(mConnectivityManager).reportNetworkConnectivity(mNetwork, false);
    }

    @Test
    public void testHandleLossRate_resultUnavalaible() throws Exception {
        checkHandleLossRate(
                PACKET_LOSS_UNAVALAIBLE,
                PacketLossCalculationResult.invalid(),
                false /* isLastStateExpectedToUpdate */,
                false /* isCallbackExpected */);
    }

    private void checkGetPacketLossRate(
            IpSecTransformState oldState, IpSecTransformState newState, int expectedLossRate)
            IpSecTransformState oldState,
            IpSecTransformState newState,
            PacketLossCalculationResult expectedLossRate)
            throws Exception {
        assertEquals(
                expectedLossRate,
@@ -362,14 +370,30 @@ public class IpSecPacketLossDetectorTest extends NetworkEvaluationTestBase {
            throws Exception {
        final IpSecTransformState newState =
                newTransformState(rxSeqNo, packetCount, newReplayBitmap(packetInWin));
        checkGetPacketLossRate(
                oldState, newState, PacketLossCalculationResult.valid(expectedDataLossRate));
    }

    private void checkGetPacketLossRate(
            IpSecTransformState oldState,
            int rxSeqNo,
            int packetCount,
            int packetInWin,
            PacketLossCalculationResult expectedDataLossRate)
            throws Exception {
        final IpSecTransformState newState =
                newTransformState(rxSeqNo, packetCount, newReplayBitmap(packetInWin));
        checkGetPacketLossRate(oldState, newState, expectedDataLossRate);
    }

    @Test
    public void testGetPacketLossRate_replayWindowUnchanged() throws Exception {
        checkGetPacketLossRate(
                mTransformStateInitial, mTransformStateInitial, PACKET_LOSS_UNAVALAIBLE);
        checkGetPacketLossRate(mTransformStateInitial, 3000, 2000, 2000, PACKET_LOSS_UNAVALAIBLE);
                mTransformStateInitial,
                mTransformStateInitial,
                PacketLossCalculationResult.invalid());
        checkGetPacketLossRate(
                mTransformStateInitial, 3000, 2000, 2000, PacketLossCalculationResult.invalid());
    }

    @Test