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
This commit is contained in:
Hnin Naing 2025-09-11 23:46:54 +00:00
commit 4ab80490ae
5 changed files with 74 additions and 5 deletions

View file

@ -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. */

View file

@ -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);
}
}

View file

@ -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<UnderlyingNetworkEvaluator> getSortedUnderlyingNetworks() {
@ -489,6 +507,7 @@ public class UnderlyingNetworkController {
}
TreeSet<UnderlyingNetworkEvaluator> 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();
}
}
}

View file

@ -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)

View file

@ -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<Integer> 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<VcnUnderlyingNetworkTemplate> 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<VcnUnderlyingNetworkTemplate> networkTemplates = new ArrayList();