From 4ab80490ae9937997fe8db8eb13d4d59618d4bbe Mon Sep 17 00:00:00 2001 From: Hnin Naing Date: Thu, 11 Sep 2025 23:46:54 +0000 Subject: [PATCH] Log validated underlying network count that's available for VCN underlying network selection Flag: EXEMPT METRICS Test: atest FrameworksVcnTests, CtsVcnTestCases Bug: 288600040 Change-Id: Ia1b51aa64388bc5c167f3a1081d8683d98fe0bef --- .../server/vcn/VcnGatewayConnection.java | 9 +++++- .../server/vcn/metrics/VcnMetrics.java | 11 ++++++-- .../UnderlyingNetworkController.java | 28 ++++++++++++++++++- .../vcn/VcnGatewayConnectionTestBase.java | 3 +- .../UnderlyingNetworkControllerTest.java | 28 +++++++++++++++++++ 5 files changed, 74 insertions(+), 5 deletions(-) diff --git a/Vcn/service-b/src/com/android/server/vcn/VcnGatewayConnection.java b/Vcn/service-b/src/com/android/server/vcn/VcnGatewayConnection.java index 57ef5da9a9..0a160fc097 100644 --- a/Vcn/service-b/src/com/android/server/vcn/VcnGatewayConnection.java +++ b/Vcn/service-b/src/com/android/server/vcn/VcnGatewayConnection.java @@ -834,6 +834,7 @@ public class VcnGatewayConnection extends StateMachine { mDeps.newUnderlyingNetworkController( mVcnContext, mConnectionConfig, + mId, subscriptionGroup, mLastSnapshot, mUnderlyingNetworkControllerCallback); @@ -2815,11 +2816,17 @@ public class VcnGatewayConnection extends StateMachine { public UnderlyingNetworkController newUnderlyingNetworkController( VcnContext vcnContext, VcnGatewayConnectionConfig connectionConfig, + int gatewayConnectionId, ParcelUuid subscriptionGroup, TelephonySubscriptionSnapshot snapshot, UnderlyingNetworkControllerCallback callback) { return new UnderlyingNetworkController( - vcnContext, connectionConfig, subscriptionGroup, snapshot, callback); + vcnContext, + connectionConfig, + gatewayConnectionId, + subscriptionGroup, + snapshot, + callback); } /** Builds a new IkeSession. */ diff --git a/Vcn/service-b/src/com/android/server/vcn/metrics/VcnMetrics.java b/Vcn/service-b/src/com/android/server/vcn/metrics/VcnMetrics.java index 0ccd4ecd4d..021606bb6d 100644 --- a/Vcn/service-b/src/com/android/server/vcn/metrics/VcnMetrics.java +++ b/Vcn/service-b/src/com/android/server/vcn/metrics/VcnMetrics.java @@ -16,7 +16,6 @@ package com.android.server.vcn.metrics; -import static com.android.server.vcn.metrics.VcnStatsLog.VCN_GATEWAY_CONNECTION_STATE_CHANGED; import static com.android.server.vcn.metrics.VcnStatsLog.VCN_GATEWAY_CONNECTION_STATE_CHANGED__GW_TEARDOWN_REASON__GATEWAY_TEARDOWN_REASON_INTERNAL_ERROR; import static com.android.server.vcn.metrics.VcnStatsLog.VCN_GATEWAY_CONNECTION_STATE_CHANGED__GW_TEARDOWN_REASON__GATEWAY_TEARDOWN_REASON_NETWORK_AGENT_UNWANTED; import static com.android.server.vcn.metrics.VcnStatsLog.VCN_GATEWAY_CONNECTION_STATE_CHANGED__GW_TEARDOWN_REASON__GATEWAY_TEARDOWN_REASON_NONE; @@ -56,7 +55,7 @@ public class VcnMetrics { /** Log an atom when a VcnGatewayConnection has entered safe mode. */ public void logEnterSafeMode(int gatewayConnectionId) { VcnStatsLog.write( - VCN_GATEWAY_CONNECTION_STATE_CHANGED, + VcnStatsLog.VCN_GATEWAY_CONNECTION_STATE_CHANGED, gatewayConnectionId, GATEWAY_TEARDOWN_REASON_NONE, true /* isInSafeMode */); @@ -125,4 +124,12 @@ public class VcnMetrics { true /* isConnected */, false /* isValidated */); } + + /** + * Log an atom about number of validated underlying network available for VCN network selection. + */ + public void logValidatedUnderlyingNetworkCount(int gatewayConnectionId, int count) { + VcnStatsLog.write( + VcnStatsLog.VCN_UNDERLYING_NETWORKS_STATE_CHANGED, gatewayConnectionId, count); + } } diff --git a/Vcn/service-b/src/com/android/server/vcn/routeselection/UnderlyingNetworkController.java b/Vcn/service-b/src/com/android/server/vcn/routeselection/UnderlyingNetworkController.java index 37ec0e8f40..1012ba4823 100644 --- a/Vcn/service-b/src/com/android/server/vcn/routeselection/UnderlyingNetworkController.java +++ b/Vcn/service-b/src/com/android/server/vcn/routeselection/UnderlyingNetworkController.java @@ -56,6 +56,7 @@ import com.android.internal.annotations.VisibleForTesting.Visibility; import com.android.modules.utils.HandlerExecutor; import com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscriptionSnapshot; import com.android.server.vcn.VcnContext; +import com.android.server.vcn.metrics.VcnMetrics; import com.android.server.vcn.routeselection.UnderlyingNetworkEvaluator.NetworkEvaluatorCallback; import java.util.ArrayList; @@ -105,19 +106,31 @@ public class UnderlyingNetworkController { @Nullable private UnderlyingNetworkRecord mCurrentRecord; @Nullable private UnderlyingNetworkRecord.Builder mRecordInProgress; + private final int mGatewayConnectionId; + private final VcnMetrics mVcnMetrics; + public UnderlyingNetworkController( @NonNull VcnContext vcnContext, @NonNull VcnGatewayConnectionConfig connectionConfig, + int gatewayConnectionId, @NonNull ParcelUuid subscriptionGroup, @NonNull TelephonySubscriptionSnapshot snapshot, @NonNull UnderlyingNetworkControllerCallback cb) { - this(vcnContext, connectionConfig, subscriptionGroup, snapshot, cb, new Dependencies()); + this( + vcnContext, + connectionConfig, + gatewayConnectionId, + subscriptionGroup, + snapshot, + cb, + new Dependencies()); } @VisibleForTesting(visibility = Visibility.PRIVATE) UnderlyingNetworkController( @NonNull VcnContext vcnContext, @NonNull VcnGatewayConnectionConfig connectionConfig, + int gatewayConnectionId, @NonNull ParcelUuid subscriptionGroup, @NonNull TelephonySubscriptionSnapshot snapshot, @NonNull UnderlyingNetworkControllerCallback cb, @@ -128,6 +141,8 @@ public class UnderlyingNetworkController { mLastSnapshot = Objects.requireNonNull(snapshot, "Missing snapshot"); mCb = Objects.requireNonNull(cb, "Missing cb"); mDeps = Objects.requireNonNull(deps, "Missing deps"); + mGatewayConnectionId = gatewayConnectionId; + mVcnMetrics = mDeps.newVcnMetrics(); mHandler = new Handler(mVcnContext.getLooper()); @@ -468,6 +483,9 @@ public class UnderlyingNetworkController { .getContext() .getSystemService(TelephonyManager.class) .unregisterTelephonyCallback(mActiveDataSubIdListener); + + // Log empty validated network count left, as a clean up state. + mVcnMetrics.logValidatedUnderlyingNetworkCount(mGatewayConnectionId, 0); } private TreeSet getSortedUnderlyingNetworks() { @@ -489,6 +507,7 @@ public class UnderlyingNetworkController { } TreeSet sorted = getSortedUnderlyingNetworks(); + mVcnMetrics.logValidatedUnderlyingNetworkCount(mGatewayConnectionId, sorted.size()); UnderlyingNetworkEvaluator candidateEvaluator = sorted.isEmpty() ? null : sorted.first(); UnderlyingNetworkRecord candidate = @@ -734,7 +753,9 @@ public class UnderlyingNetworkController { } @VisibleForTesting(visibility = Visibility.PRIVATE) + /* External dependencies, for injection in tests */ public static class Dependencies { + /** Builds a new UnderlyingNetworkEvaluator. */ public UnderlyingNetworkEvaluator newUnderlyingNetworkEvaluator( @NonNull VcnContext vcnContext, @NonNull Network network, @@ -752,5 +773,10 @@ public class UnderlyingNetworkController { carrierConfig, evaluatorCallback); } + + /** Builds a new VcnMetrics. */ + public VcnMetrics newVcnMetrics() { + return new VcnMetrics(); + } } } diff --git a/Vcn/tests/unit/java/com/android/server/vcn/VcnGatewayConnectionTestBase.java b/Vcn/tests/unit/java/com/android/server/vcn/VcnGatewayConnectionTestBase.java index 461fa9cd9c..33c6f833da 100644 --- a/Vcn/tests/unit/java/com/android/server/vcn/VcnGatewayConnectionTestBase.java +++ b/Vcn/tests/unit/java/com/android/server/vcn/VcnGatewayConnectionTestBase.java @@ -25,6 +25,7 @@ import static com.android.server.vcn.VcnTestUtils.setupIpSecManager; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.CALLS_REAL_METHODS; import static org.mockito.Mockito.atLeastOnce; @@ -228,7 +229,7 @@ public class VcnGatewayConnectionTestBase { doReturn(mUnderlyingNetworkController) .when(mDeps) - .newUnderlyingNetworkController(any(), any(), any(), any(), any()); + .newUnderlyingNetworkController(any(), any(), anyInt(), any(), any(), any()); doReturn(mVcnMetrics).when(mDeps).newVcnMetrics(); doReturn(mWakeLock) .when(mDeps) diff --git a/Vcn/tests/unit/java/com/android/server/vcn/routeselection/UnderlyingNetworkControllerTest.java b/Vcn/tests/unit/java/com/android/server/vcn/routeselection/UnderlyingNetworkControllerTest.java index b67a2fd21b..17c1ba9c86 100644 --- a/Vcn/tests/unit/java/com/android/server/vcn/routeselection/UnderlyingNetworkControllerTest.java +++ b/Vcn/tests/unit/java/com/android/server/vcn/routeselection/UnderlyingNetworkControllerTest.java @@ -71,6 +71,7 @@ import androidx.test.runner.AndroidJUnit4; import com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscriptionSnapshot; import com.android.server.vcn.VcnContext; import com.android.server.vcn.VcnNetworkProvider; +import com.android.server.vcn.metrics.VcnMetrics; import com.android.server.vcn.routeselection.UnderlyingNetworkController.Dependencies; import com.android.server.vcn.routeselection.UnderlyingNetworkController.NetworkBringupCallback; import com.android.server.vcn.routeselection.UnderlyingNetworkController.UnderlyingNetworkControllerCallback; @@ -100,6 +101,7 @@ public class UnderlyingNetworkControllerTest { private static final int INITIAL_SUB_ID_1 = 1; private static final int INITIAL_SUB_ID_2 = 2; private static final int UPDATED_SUB_ID = 3; + private static final int GATEWAY_CONNECTION_ID = 1234; private static final Set INITIAL_SUB_IDS = new ArraySet<>(Arrays.asList(INITIAL_SUB_ID_1, INITIAL_SUB_ID_2)); @@ -164,6 +166,7 @@ public class UnderlyingNetworkControllerTest { @Mock private UnderlyingNetworkControllerCallback mNetworkControllerCb; @Mock private NetworkEvaluatorCallback mEvaluatorCallback; @Mock private Network mNetwork; + @Mock private VcnMetrics mVcnMetrics; @Spy private Dependencies mDependencies = new Dependencies(); @@ -218,11 +221,13 @@ public class UnderlyingNetworkControllerTest { doReturn(mNetworkEvaluator) .when(mDependencies) .newUnderlyingNetworkEvaluator(any(), any(), any(), any(), any(), any(), any()); + doReturn(mVcnMetrics).when(mDependencies).newVcnMetrics(); mUnderlyingNetworkController = new UnderlyingNetworkController( mVcnContext, VcnGatewayConnectionConfigTest.buildTestConfig(), + GATEWAY_CONNECTION_ID, SUB_GROUP, mSubscriptionSnapshot, mNetworkControllerCb, @@ -268,6 +273,7 @@ public class UnderlyingNetworkControllerTest { new UnderlyingNetworkController( vcnContext, VcnGatewayConnectionConfigTest.buildTestConfig(), + GATEWAY_CONNECTION_ID, SUB_GROUP, mSubscriptionSnapshot, mNetworkControllerCb); @@ -320,6 +326,7 @@ public class UnderlyingNetworkControllerTest { new UnderlyingNetworkController( mVcnContext, VcnGatewayConnectionConfigTest.buildTestConfig(networkTemplates), + GATEWAY_CONNECTION_ID, SUB_GROUP, mSubscriptionSnapshot, mNetworkControllerCb); @@ -361,6 +368,7 @@ public class UnderlyingNetworkControllerTest { new UnderlyingNetworkController( mVcnContext, VcnGatewayConnectionConfigTest.buildTestConfig(networkTemplates), + GATEWAY_CONNECTION_ID, SUB_GROUP, mSubscriptionSnapshot, mNetworkControllerCb); @@ -515,6 +523,7 @@ public class UnderlyingNetworkControllerTest { .unregisterNetworkCallback(any(NetworkBringupCallback.class)); verify(mConnectivityManager) .unregisterNetworkCallback(any(UnderlyingNetworkListener.class)); + verify(mVcnMetrics).logValidatedUnderlyingNetworkCount(eq(GATEWAY_CONNECTION_ID), eq(0)); } private static UnderlyingNetworkRecord getTestNetworkRecord( @@ -780,6 +789,7 @@ public class UnderlyingNetworkControllerTest { new UnderlyingNetworkController( mVcnContext, VcnGatewayConnectionConfigTest.buildTestConfig(networkTemplates), + GATEWAY_CONNECTION_ID, SUB_GROUP, mSubscriptionSnapshot, mNetworkControllerCb, @@ -834,6 +844,24 @@ public class UnderlyingNetworkControllerTest { verify(expectedEvaluator, never()).setIsSelected(eq(true), any(), any(), any(), any()); } + @Test + public void testValidatedUnderlyingNetworkCountsLogged() { + final List networkTemplates = new ArrayList(); + networkTemplates.add(CELL_TEMPLATE_DUN); + networkTemplates.add(CELL_TEMPLATE_CBS); + + // Bring up CBS network + UnderlyingNetworkListener cb = setupControllerAndGetNetworkListener(networkTemplates); + bringupNetworkAndGetEvaluator(cb, CBS_NETWORK_CAPABILITIES, networkTemplates); + + verify(mVcnMetrics).logValidatedUnderlyingNetworkCount(eq(GATEWAY_CONNECTION_ID), eq(1)); + + // Bring up DUN network + bringupNetworkAndGetEvaluator(cb, DUN_NETWORK_CAPABILITIES, networkTemplates); + + verify(mVcnMetrics).logValidatedUnderlyingNetworkCount(eq(GATEWAY_CONNECTION_ID), eq(2)); + } + @Test public void testSelectMorePreferredNetwork() { final List networkTemplates = new ArrayList();