diff --git a/src/com/android/settings/network/telephony/CarrierConfigManagerExt.kt b/src/com/android/settings/network/telephony/CarrierConfigManagerExt.kt new file mode 100644 index 00000000000..b4211854c0e --- /dev/null +++ b/src/com/android/settings/network/telephony/CarrierConfigManagerExt.kt @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2024 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.settings.network.telephony + +import android.os.PersistableBundle +import android.telephony.CarrierConfigManager +import android.telephony.SubscriptionManager +import androidx.core.os.persistableBundleOf + +/** + * Gets the configuration values of the specified config keys applied. + */ +fun CarrierConfigManager.safeGetConfig( + keys: List, + subId: Int = SubscriptionManager.getDefaultSubscriptionId(), +): PersistableBundle = try { + getConfigForSubId(subId, *keys.toTypedArray()) +} catch (e: IllegalStateException) { + // The CarrierConfigLoader (the service implemented the CarrierConfigManager) hasn't been + // initialized yet. This may occurs during very early phase of phone booting up or when Phone + // process has been restarted. + // Settings should not assume Carrier config loader (and any other system services as well) are + // always available. If not available, use default value instead. + persistableBundleOf() +} diff --git a/src/com/android/settings/system/ClientInitiatedActionRepository.kt b/src/com/android/settings/system/ClientInitiatedActionRepository.kt index 24c04b4b2f4..715acfa8c7b 100644 --- a/src/com/android/settings/system/ClientInitiatedActionRepository.kt +++ b/src/com/android/settings/system/ClientInitiatedActionRepository.kt @@ -20,6 +20,7 @@ import android.content.Context import android.content.Intent import android.telephony.CarrierConfigManager import android.util.Log +import com.android.settings.network.telephony.safeGetConfig class ClientInitiatedActionRepository(private val context: Context) { private val configManager = context.getSystemService(CarrierConfigManager::class.java)!! @@ -29,11 +30,13 @@ class ClientInitiatedActionRepository(private val context: Context) { */ fun onSystemUpdate() { val bundle = - configManager.getConfig( - CarrierConfigManager.KEY_CI_ACTION_ON_SYS_UPDATE_BOOL, - CarrierConfigManager.KEY_CI_ACTION_ON_SYS_UPDATE_INTENT_STRING, - CarrierConfigManager.KEY_CI_ACTION_ON_SYS_UPDATE_EXTRA_STRING, - CarrierConfigManager.KEY_CI_ACTION_ON_SYS_UPDATE_EXTRA_VAL_STRING, + configManager.safeGetConfig( + keys = listOf( + CarrierConfigManager.KEY_CI_ACTION_ON_SYS_UPDATE_BOOL, + CarrierConfigManager.KEY_CI_ACTION_ON_SYS_UPDATE_INTENT_STRING, + CarrierConfigManager.KEY_CI_ACTION_ON_SYS_UPDATE_EXTRA_STRING, + CarrierConfigManager.KEY_CI_ACTION_ON_SYS_UPDATE_EXTRA_VAL_STRING, + ), ) if (!bundle.getBoolean(CarrierConfigManager.KEY_CI_ACTION_ON_SYS_UPDATE_BOOL)) return diff --git a/tests/spa_unit/src/com/android/settings/network/telephony/CarrierConfigManagerExtTest.kt b/tests/spa_unit/src/com/android/settings/network/telephony/CarrierConfigManagerExtTest.kt new file mode 100644 index 00000000000..5a82f99838c --- /dev/null +++ b/tests/spa_unit/src/com/android/settings/network/telephony/CarrierConfigManagerExtTest.kt @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2024 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.settings.network.telephony + +import android.content.Context +import android.telephony.CarrierConfigManager +import androidx.core.os.persistableBundleOf +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.google.common.truth.Truth.assertThat +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.kotlin.any +import org.mockito.kotlin.doReturn +import org.mockito.kotlin.doThrow +import org.mockito.kotlin.eq +import org.mockito.kotlin.mock +import org.mockito.kotlin.stub + +@RunWith(AndroidJUnit4::class) +class CarrierConfigManagerExtTest { + + private val mockCarrierConfigManager = mock() + + private val context = mock { + on { getSystemService(CarrierConfigManager::class.java) } doReturn mockCarrierConfigManager + } + + @Test + fun safeGetConfig_managerReturnKeyValue_returnNonEmptyBundle() { + mockCarrierConfigManager.stub { + on { getConfigForSubId(any(), eq(KEY)) } doReturn persistableBundleOf(KEY to VALUE) + } + val carrierConfigManager = context.getSystemService(CarrierConfigManager::class.java)!! + + val bundle = carrierConfigManager.safeGetConfig(listOf(KEY)) + + assertThat(bundle.getString(KEY)).isEqualTo(VALUE) + } + + @Test + fun safeGetConfig_managerThrowIllegalStateException_returnEmptyBundle() { + mockCarrierConfigManager.stub { + on { getConfigForSubId(any(), eq(KEY)) } doThrow IllegalStateException() + } + val carrierConfigManager = context.getSystemService(CarrierConfigManager::class.java)!! + + val bundle = carrierConfigManager.safeGetConfig(listOf(KEY)) + + assertThat(bundle.containsKey(KEY)).isFalse() + } + + private companion object { + const val KEY = "key" + const val VALUE = "value" + } +} diff --git a/tests/spa_unit/src/com/android/settings/system/ClientInitiatedActionRepositoryTest.kt b/tests/spa_unit/src/com/android/settings/system/ClientInitiatedActionRepositoryTest.kt index f202668c94b..2f52031e7aa 100644 --- a/tests/spa_unit/src/com/android/settings/system/ClientInitiatedActionRepositoryTest.kt +++ b/tests/spa_unit/src/com/android/settings/system/ClientInitiatedActionRepositoryTest.kt @@ -25,7 +25,6 @@ import com.google.common.truth.Truth.assertThat import org.junit.Test import org.junit.runner.RunWith import org.mockito.kotlin.any -import org.mockito.kotlin.anyVararg import org.mockito.kotlin.argumentCaptor import org.mockito.kotlin.doReturn import org.mockito.kotlin.mock @@ -47,7 +46,7 @@ class ClientInitiatedActionRepositoryTest { @Test fun onSystemUpdate_notEnabled() { mockCarrierConfigManager.stub { - on { getConfig(anyVararg()) } doReturn persistableBundleOf() + on { getConfigForSubId(any(), any()) } doReturn persistableBundleOf() } repository.onSystemUpdate() @@ -58,7 +57,7 @@ class ClientInitiatedActionRepositoryTest { @Test fun onSystemUpdate_enabled() { mockCarrierConfigManager.stub { - on { getConfig(anyVararg()) } doReturn persistableBundleOf( + on { getConfigForSubId(any(), any()) } doReturn persistableBundleOf( CarrierConfigManager.KEY_CI_ACTION_ON_SYS_UPDATE_BOOL to true, CarrierConfigManager.KEY_CI_ACTION_ON_SYS_UPDATE_INTENT_STRING to ACTION, )