/* * Copyright (C) 2025 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server import android.app.PendingIntent import android.content.Intent import android.net.ConnectivityManager.NetworkCallback import android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET import android.net.NetworkRequest import android.net.NetworkRequest.Type import android.os.Build import androidx.test.filters.SmallTest import com.android.server.connectivity.ConnectivityFlags.SATISFIED_BY_LOCAL_NETWORK_METRICS import com.android.testutils.DevSdkIgnoreRule import com.android.testutils.DevSdkIgnoreRunner import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.ArgumentMatchers.any import org.mockito.ArgumentMatchers.anyInt import org.mockito.ArgumentMatchers.argThat import org.mockito.Mockito.clearInvocations import org.mockito.Mockito.eq import org.mockito.Mockito.never import org.mockito.Mockito.timeout import org.mockito.Mockito.verify import org.mockito.Mockito.verifyNoMoreInteractions @RunWith(DevSdkIgnoreRunner::class) @SmallTest @DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R) class CSSatisfiedByLocalNetworkMetricsTest : CSTest() { companion object { private const val TEST_UID = 12345 } private val request = NetworkRequest.Builder().addCapability(NET_CAPABILITY_INTERNET).build() private val mockCb = mock() private val mockPendingIntent by lazy { PendingIntent.getBroadcast( context, 0, Intent("TEST_ACTION"), PendingIntent.FLAG_IMMUTABLE ) } @Before override fun setUp() { super.setUp() deps.callingUid = TEST_UID // Clear invocations generated by satisfiedByLocalNetworkMetrics#start(). clearInvocations(satisfiedByLocalNetworkMetrics) } private fun verifyLogRequest(reqType: Type, uid: Int) { verify(satisfiedByLocalNetworkMetrics, timeout(HANDLER_TIMEOUT_MS)) .logRequest(argThat { it.type == reqType }, eq(uid)) verifyNoMoreInteractions(satisfiedByLocalNetworkMetrics) clearInvocations(satisfiedByLocalNetworkMetrics) } private fun verifyNoLogRequest() { waitForIdle() verify(satisfiedByLocalNetworkMetrics, never()).logRequest(any(), anyInt()) } @Test fun testRequestNetwork() { cm.requestNetwork(request, mockCb) waitForIdle() verifyLogRequest(Type.REQUEST, TEST_UID) } @Test fun testListenForNetwork() { cm.registerNetworkCallback(request, mockCb) waitForIdle() verifyLogRequest(Type.LISTEN, TEST_UID) } @Test fun testListenForBestNetwork() { cm.registerBestMatchingNetworkCallback(request, mockCb, csHandler) waitForIdle() verifyLogRequest(Type.LISTEN_FOR_BEST, TEST_UID) } @Test fun testPendingRequestForNetwork() { cm.requestNetwork(request, mockPendingIntent) waitForIdle() verifyLogRequest(Type.REQUEST, TEST_UID) } @Test fun testPendingListenForNetwork() { cm.registerNetworkCallback(request, mockPendingIntent) waitForIdle() verifyLogRequest(Type.LISTEN, TEST_UID) } @Test @FeatureFlags([Flag(name = SATISFIED_BY_LOCAL_NETWORK_METRICS, enabled = false)]) fun testLogRequest_FlagDisabled() { cm.requestNetwork(request, mockCb) waitForIdle() verifyNoLogRequest() cm.unregisterNetworkCallback(mockCb) cm.registerNetworkCallback(request, mockCb) waitForIdle() verifyNoLogRequest() } }