Merge "Wait for carrier config to apply in tests" into main

This commit is contained in:
Treehugger Robot 2025-02-06 00:03:08 -08:00 • committed by Gerrit Code Review
commit 5ad3246434
2 changed files with 41 additions and 8 deletions

View file

@ -18,28 +18,36 @@ package com.android.testutils.com.android.testutils
import android.Manifest.permission.MODIFY_PHONE_STATE
import android.Manifest.permission.READ_PHONE_STATE
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.ConditionVariable
import android.os.PersistableBundle
import android.telephony.CarrierConfigManager
import android.telephony.CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED
import android.telephony.SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX
import android.util.Log
import androidx.test.platform.app.InstrumentationRegistry
import com.android.modules.utils.build.SdkLevel.isAtLeastU
import com.android.testutils.runAsShell
import com.android.testutils.tryTest
import kotlin.test.assertNotNull
import kotlin.test.assertTrue
import org.junit.rules.TestRule
import org.junit.runner.Description
import org.junit.runners.model.Statement
private val TAG = CarrierConfigRule::class.simpleName
private const val CARRIER_CONFIG_CHANGE_TIMEOUT_MS = 10_000L
/**
* A [TestRule] that helps set [CarrierConfigManager] overrides for tests and clean up the test
* configuration automatically on teardown.
*/
class CarrierConfigRule : TestRule {
private val ccm by lazy { InstrumentationRegistry.getInstrumentation().context.getSystemService(
CarrierConfigManager::class.java
) }
private val context by lazy { InstrumentationRegistry.getInstrumentation().context }
private val ccm by lazy { context.getSystemService(CarrierConfigManager::class.java) }
// Map of (subId) -> (original values of overridden settings)
private val originalConfigs = mutableMapOf<Int, PersistableBundle>()
@ -61,6 +69,33 @@ class CarrierConfigRule : TestRule {
}
}
private class ConfigChangeReceiver(private val subId: Int) : BroadcastReceiver() {
val cv = ConditionVariable()
override fun onReceive(context: Context, intent: Intent) {
if (intent.action != ACTION_CARRIER_CONFIG_CHANGED ||
intent.getIntExtra(EXTRA_SUBSCRIPTION_INDEX, -1) != subId) {
return
}
// This may race with other config changes for the same subId, but there is no way to
// know which update is being reported, and querying the override would return the
// latest values even before the config is applied. Config changes should be rare, so it
// is unlikely they would happen exactly after the override applied here and cause
// flakes.
cv.open()
}
}
private fun overrideConfigAndWait(subId: Int, config: PersistableBundle) {
val changeReceiver = ConfigChangeReceiver(subId)
context.registerReceiver(changeReceiver, IntentFilter(ACTION_CARRIER_CONFIG_CHANGED))
ccm.overrideConfig(subId, config)
assertTrue(
changeReceiver.cv.block(CARRIER_CONFIG_CHANGE_TIMEOUT_MS),
"Timed out waiting for config change for subId $subId"
)
context.unregisterReceiver(changeReceiver)
}
/**
* Add carrier config overrides with the specified configuration.
*
@ -79,7 +114,7 @@ class CarrierConfigRule : TestRule {
originalConfig.putAll(previousValues)
runAsShell(MODIFY_PHONE_STATE) {
ccm.overrideConfig(subId, config)
overrideConfigAndWait(subId, config)
}
}
@ -93,10 +128,10 @@ class CarrierConfigRule : TestRule {
runAsShell(MODIFY_PHONE_STATE) {
originalConfigs.forEach { (subId, config) ->
try {
// Do not use overrideConfig with null, as it would reset configs that may
// Do not use null as the config to reset, as it would reset configs that may
// have been set by target preparers such as
// ConnectivityTestTargetPreparer / CarrierConfigSetupTest.
ccm.overrideConfig(subId, config)
overrideConfigAndWait(subId, config)
} catch (e: Throwable) {
Log.e(TAG, "Error resetting carrier config for subId $subId")
}

View file

@ -743,7 +743,6 @@ class NetworkAgentTest {
}
return@tryTest
}
cv.close()
if (hold) {
carrierConfigRule.addConfigOverrides(subId, PersistableBundle().also {
it.putStringArray(CarrierConfigManager.KEY_CARRIER_CERTIFICATE_STRING_ARRAY,
@ -752,7 +751,6 @@ class NetworkAgentTest {
} else {
carrierConfigRule.cleanUpNow()
}
assertTrue(cv.block(DEFAULT_TIMEOUT_MS), "Can't change carrier privilege")
} cleanup @JvmSerializableLambda {
runAsShell(READ_PRIVILEGED_PHONE_STATE) @JvmSerializableLambda {
tm.unregisterCarrierPrivilegesCallback(cpb)