Loading src/com/android/settings/network/telephony/MobileNetworkPhoneNumberPreferenceController.kt +19 −72 Original line number Diff line number Diff line Loading @@ -17,47 +17,35 @@ package com.android.settings.network.telephony import android.content.Context import android.telephony.SubscriptionInfo import android.telephony.SubscriptionManager import android.util.Log import androidx.annotation.VisibleForTesting import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.lifecycleScope import androidx.preference.Preference import androidx.preference.PreferenceScreen import com.android.settings.R import com.android.settings.flags.Flags import com.android.settings.network.SubscriptionInfoListViewModel import com.android.settings.network.SubscriptionUtil import com.android.settingslib.spa.framework.util.collectLatestWithLifecycle import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.map import kotlinx.coroutines.launch import kotlinx.coroutines.withContext /** * Preference controller for "Phone number" */ class MobileNetworkPhoneNumberPreferenceController(context: Context, key: String) : TelephonyBasePreferenceController(context, key) { /** Preference controller for "Phone number" */ class MobileNetworkPhoneNumberPreferenceController @JvmOverloads constructor( context: Context, key: String, private val subscriptionRepository: SubscriptionRepository = SubscriptionRepository(context), ) : TelephonyBasePreferenceController(context, key) { private lateinit var lazyViewModel: Lazy<SubscriptionInfoListViewModel> private lateinit var preference: Preference private var phoneNumber = String() fun init(fragment: Fragment, subId: Int) { lazyViewModel = fragment.viewModels() fun init(subId: Int) { mSubId = subId } override fun getAvailabilityStatus(subId: Int): Int = when { override fun getAvailabilityStatus(subId: Int): Int = when { !Flags.isDualSimOnboardingEnabled() -> CONDITIONALLY_UNAVAILABLE SubscriptionManager.isValidSubscriptionId(subId) && SubscriptionUtil.isSimHardwareVisible(mContext) -> AVAILABLE SubscriptionManager.isValidSubscriptionId(subId) && SubscriptionUtil.isSimHardwareVisible(mContext) -> AVAILABLE else -> CONDITIONALLY_UNAVAILABLE } Loading @@ -67,53 +55,12 @@ class MobileNetworkPhoneNumberPreferenceController(context: Context, key: String } override fun onViewCreated(viewLifecycleOwner: LifecycleOwner) { if (!this::lazyViewModel.isInitialized) { Log.e( this.javaClass.simpleName, "lateinit property lazyViewModel has not been initialized" ) return } val viewModel by lazyViewModel val coroutineScope = viewLifecycleOwner.lifecycleScope viewModel.subscriptionInfoListFlow .map { subscriptionInfoList -> subscriptionInfoList .firstOrNull { subInfo -> subInfo.subscriptionId == mSubId } } .flowOn(Dispatchers.Default) .collectLatestWithLifecycle(viewLifecycleOwner) { it?.let { coroutineScope.launch { refreshData(it) } } subscriptionRepository.phoneNumberFlow(mSubId).collectLatestWithLifecycle( viewLifecycleOwner) { phoneNumber -> preference.summary = phoneNumber ?: getStringUnknown() } } @VisibleForTesting suspend fun refreshData(subscriptionInfo: SubscriptionInfo){ withContext(Dispatchers.Default) { phoneNumber = getFormattedPhoneNumber(subscriptionInfo) } refreshUi() } private fun refreshUi(){ preference.summary = phoneNumber } private fun getFormattedPhoneNumber(subscriptionInfo: SubscriptionInfo?): String { val phoneNumber = SubscriptionUtil.getBidiFormattedPhoneNumber( mContext, subscriptionInfo ) return phoneNumber ?.let { return it.ifEmpty { getStringUnknown() } } ?: getStringUnknown() } private fun getStringUnknown(): String { return mContext.getString(R.string.device_info_default) } Loading src/com/android/settings/network/telephony/MobileNetworkSettings.java +1 −1 Original line number Diff line number Diff line Loading @@ -257,7 +257,7 @@ public class MobileNetworkSettings extends AbstractMobileNetworkSettings impleme use(NrDisabledInDsdsFooterPreferenceController.class).init(mSubId); use(MobileNetworkSpnPreferenceController.class).init(this, mSubId); use(MobileNetworkPhoneNumberPreferenceController.class).init(this, mSubId); use(MobileNetworkPhoneNumberPreferenceController.class).init(mSubId); use(MobileNetworkImeiPreferenceController.class).init(this, mSubId); final MobileDataPreferenceController mobileDataPreferenceController = Loading src/com/android/settings/network/telephony/SubscriptionRepository.kt +33 −11 Original line number Diff line number Diff line Loading @@ -24,13 +24,14 @@ import androidx.lifecycle.LifecycleOwner import com.android.settings.network.SubscriptionUtil import com.android.settingslib.spa.framework.util.collectLatestWithLifecycle import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.asExecutor import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.callbackFlow import kotlinx.coroutines.flow.conflate import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.filterNot import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.map Loading @@ -52,7 +53,7 @@ class SubscriptionRepository(private val context: Context) { /** Flow of whether the subscription enabled for the given [subId]. */ fun isSubscriptionEnabledFlow(subId: Int): Flow<Boolean> { if (!SubscriptionManager.isValidSubscriptionId(subId)) return flowOf(false) return context.subscriptionsChangedFlow() return subscriptionsChangedFlow() .map { subscriptionManager.isSubscriptionEnabled(subId) } .conflate() .onEach { Log.d(TAG, "[$subId] isSubscriptionEnabledFlow: $it") } Loading Loading @@ -87,12 +88,30 @@ class SubscriptionRepository(private val context: Context) { }.conflate().onEach { Log.d(TAG, "subscriptions changed") }.flowOn(Dispatchers.Default) /** Flow of active subscription ids. */ fun activeSubscriptionIdListFlow(): Flow<List<Int>> = context.subscriptionsChangedFlow() fun activeSubscriptionIdListFlow(): Flow<List<Int>> = subscriptionsChangedFlow() .map { subscriptionManager.activeSubscriptionIdList.sorted() } .distinctUntilChanged() .conflate() .onEach { Log.d(TAG, "activeSubscriptionIdList: $it") } .flowOn(Dispatchers.Default) fun activeSubscriptionInfoFlow(subId: Int): Flow<SubscriptionInfo?> = subscriptionsChangedFlow() .map { subscriptionManager.getActiveSubscriptionInfo(subId) } .distinctUntilChanged() .conflate() .flowOn(Dispatchers.Default) @OptIn(ExperimentalCoroutinesApi::class) fun phoneNumberFlow(subId: Int): Flow<String?> = activeSubscriptionInfoFlow(subId).flatMapLatest { subInfo -> if (subInfo != null) { context.phoneNumberFlow(subInfo) } else { flowOf(null) } } } val Context.subscriptionManager: SubscriptionManager? Loading @@ -100,9 +119,12 @@ val Context.subscriptionManager: SubscriptionManager? fun Context.requireSubscriptionManager(): SubscriptionManager = subscriptionManager!! fun Context.phoneNumberFlow(subscriptionInfo: SubscriptionInfo) = subscriptionsChangedFlow().map { SubscriptionUtil.getBidiFormattedPhoneNumber(this, subscriptionInfo) }.filterNot { it.isNullOrEmpty() }.flowOn(Dispatchers.Default) fun Context.phoneNumberFlow(subscriptionInfo: SubscriptionInfo): Flow<String?> = subscriptionsChangedFlow() .map { SubscriptionUtil.getBidiFormattedPhoneNumber(this, subscriptionInfo) } .distinctUntilChanged() .conflate() .flowOn(Dispatchers.Default) fun Context.subscriptionsChangedFlow(): Flow<Unit> = SubscriptionRepository(this).subscriptionsChangedFlow() Loading tests/spa_unit/src/com/android/settings/network/telephony/MobileNetworkPhoneNumberPreferenceControllerTest.kt +35 −61 Original line number Diff line number Diff line Loading @@ -17,8 +17,7 @@ package com.android.settings.network.telephony import android.content.Context import android.telephony.SubscriptionInfo import androidx.fragment.app.Fragment import androidx.lifecycle.testing.TestLifecycleOwner import androidx.preference.Preference import androidx.preference.PreferenceManager import androidx.test.core.app.ApplicationProvider Loading @@ -26,17 +25,19 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import com.android.dx.mockito.inline.extended.ExtendedMockito import com.android.settings.R import com.android.settings.core.BasePreferenceController import com.android.settings.network.SubscriptionInfoListViewModel import com.android.settings.network.SubscriptionUtil import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.delay import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.runBlocking import org.junit.After import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.MockitoSession import org.mockito.kotlin.any import org.mockito.kotlin.doReturn import org.mockito.kotlin.mock import org.mockito.kotlin.stub import org.mockito.kotlin.whenever import org.mockito.quality.Strictness Loading @@ -44,29 +45,25 @@ import org.mockito.quality.Strictness class MobileNetworkPhoneNumberPreferenceControllerTest { private lateinit var mockSession: MockitoSession private val mockViewModels = mock<Lazy<SubscriptionInfoListViewModel>>() private val mockFragment = mock<Fragment>{ val viewmodel = mockViewModels } private var mockPhoneNumber = String() private val context: Context = ApplicationProvider.getApplicationContext() private val controller = MobileNetworkPhoneNumberPreferenceController(context, TEST_KEY) private val mockSubscriptionRepository = mock<SubscriptionRepository>() private val controller = MobileNetworkPhoneNumberPreferenceController(context, TEST_KEY, mockSubscriptionRepository) private val preference = Preference(context).apply { key = TEST_KEY } private val preferenceScreen = PreferenceManager(context).createPreferenceScreen(context) @Before fun setUp() { mockSession = ExtendedMockito.mockitoSession() .initMocks(this) mockSession = ExtendedMockito.mockitoSession() .mockStatic(SubscriptionUtil::class.java) .strictness(Strictness.LENIENT) .startMocking() preferenceScreen.addPreference(preference) controller.init(SUB_ID) controller.displayPreference(preferenceScreen) whenever(SubscriptionUtil.getBidiFormattedPhoneNumber(any(),any())).thenReturn(mockPhoneNumber) } @After Loading @@ -75,41 +72,29 @@ class MobileNetworkPhoneNumberPreferenceControllerTest { } @Test fun refreshData_getEmptyPhoneNumber_preferenceIsNotVisible() = runBlocking { fun onViewCreated_cannotGetPhoneNumber_displayUnknown() = runBlocking { whenever(SubscriptionUtil.isSimHardwareVisible(context)).thenReturn(true) whenever(SubscriptionUtil.getActiveSubscriptions(any())).thenReturn( listOf( SUB_INFO_1, SUB_INFO_2 ) ) var mockSubId = 2 controller.init(mockFragment, mockSubId) mockPhoneNumber = String() controller.refreshData(SUB_INFO_2) assertThat(preference.summary).isEqualTo( context.getString(R.string.device_info_default)) mockSubscriptionRepository.stub { on { phoneNumberFlow(SUB_ID) } doReturn flowOf(null) } controller.onViewCreated(TestLifecycleOwner()) delay(100) assertThat(preference.summary).isEqualTo(context.getString(R.string.device_info_default)) } @Test fun refreshData_getPhoneNumber_preferenceSummaryIsExpected() = runBlocking { fun onViewCreated_canGetPhoneNumber_displayPhoneNumber() = runBlocking { whenever(SubscriptionUtil.isSimHardwareVisible(context)).thenReturn(true) whenever(SubscriptionUtil.getActiveSubscriptions(any())).thenReturn( listOf( SUB_INFO_1, SUB_INFO_2 ) ) var mockSubId = 2 controller.init(mockFragment, mockSubId) mockPhoneNumber = "test phone number" whenever(SubscriptionUtil.getBidiFormattedPhoneNumber(any(),any())).thenReturn(mockPhoneNumber) controller.refreshData(SUB_INFO_2) assertThat(preference.summary).isEqualTo(mockPhoneNumber) mockSubscriptionRepository.stub { on { phoneNumberFlow(SUB_ID) } doReturn flowOf(PHONE_NUMBER) } controller.onViewCreated(TestLifecycleOwner()) delay(100) assertThat(preference.summary).isEqualTo(PHONE_NUMBER) } @Test Loading @@ -123,18 +108,7 @@ class MobileNetworkPhoneNumberPreferenceControllerTest { private companion object { const val TEST_KEY = "test_key" const val DISPLAY_NAME_1 = "Sub 1" const val DISPLAY_NAME_2 = "Sub 2" val SUB_INFO_1: SubscriptionInfo = SubscriptionInfo.Builder().apply { setId(1) setDisplayName(DISPLAY_NAME_1) }.build() val SUB_INFO_2: SubscriptionInfo = SubscriptionInfo.Builder().apply { setId(2) setDisplayName(DISPLAY_NAME_2) }.build() const val SUB_ID = 10 const val PHONE_NUMBER = "1234567890" } } tests/spa_unit/src/com/android/settings/network/telephony/SubscriptionRepositoryTest.kt +16 −0 Original line number Diff line number Diff line Loading @@ -204,6 +204,22 @@ class SubscriptionRepositoryTest { assertThat(phoneNumber).isEqualTo(NUMBER_1) } @Test fun phoneNumberFlow_withSubId() = runBlocking { val subInfo = SubscriptionInfo.Builder().apply { setId(SUB_ID_IN_SLOT_1) setMcc(MCC) }.build() mockSubscriptionManager.stub { on { getActiveSubscriptionInfo(SUB_ID_IN_SLOT_1) } doReturn subInfo on { getPhoneNumber(SUB_ID_IN_SLOT_1) } doReturn NUMBER_1 } val phoneNumber = repository.phoneNumberFlow(SUB_ID_IN_SLOT_1).firstWithTimeoutOrNull() assertThat(phoneNumber).isEqualTo(NUMBER_1) } private companion object { const val SIM_SLOT_INDEX_0 = 0 const val SUB_ID_IN_SLOT_0 = 2 Loading Loading
src/com/android/settings/network/telephony/MobileNetworkPhoneNumberPreferenceController.kt +19 −72 Original line number Diff line number Diff line Loading @@ -17,47 +17,35 @@ package com.android.settings.network.telephony import android.content.Context import android.telephony.SubscriptionInfo import android.telephony.SubscriptionManager import android.util.Log import androidx.annotation.VisibleForTesting import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.lifecycleScope import androidx.preference.Preference import androidx.preference.PreferenceScreen import com.android.settings.R import com.android.settings.flags.Flags import com.android.settings.network.SubscriptionInfoListViewModel import com.android.settings.network.SubscriptionUtil import com.android.settingslib.spa.framework.util.collectLatestWithLifecycle import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.map import kotlinx.coroutines.launch import kotlinx.coroutines.withContext /** * Preference controller for "Phone number" */ class MobileNetworkPhoneNumberPreferenceController(context: Context, key: String) : TelephonyBasePreferenceController(context, key) { /** Preference controller for "Phone number" */ class MobileNetworkPhoneNumberPreferenceController @JvmOverloads constructor( context: Context, key: String, private val subscriptionRepository: SubscriptionRepository = SubscriptionRepository(context), ) : TelephonyBasePreferenceController(context, key) { private lateinit var lazyViewModel: Lazy<SubscriptionInfoListViewModel> private lateinit var preference: Preference private var phoneNumber = String() fun init(fragment: Fragment, subId: Int) { lazyViewModel = fragment.viewModels() fun init(subId: Int) { mSubId = subId } override fun getAvailabilityStatus(subId: Int): Int = when { override fun getAvailabilityStatus(subId: Int): Int = when { !Flags.isDualSimOnboardingEnabled() -> CONDITIONALLY_UNAVAILABLE SubscriptionManager.isValidSubscriptionId(subId) && SubscriptionUtil.isSimHardwareVisible(mContext) -> AVAILABLE SubscriptionManager.isValidSubscriptionId(subId) && SubscriptionUtil.isSimHardwareVisible(mContext) -> AVAILABLE else -> CONDITIONALLY_UNAVAILABLE } Loading @@ -67,53 +55,12 @@ class MobileNetworkPhoneNumberPreferenceController(context: Context, key: String } override fun onViewCreated(viewLifecycleOwner: LifecycleOwner) { if (!this::lazyViewModel.isInitialized) { Log.e( this.javaClass.simpleName, "lateinit property lazyViewModel has not been initialized" ) return } val viewModel by lazyViewModel val coroutineScope = viewLifecycleOwner.lifecycleScope viewModel.subscriptionInfoListFlow .map { subscriptionInfoList -> subscriptionInfoList .firstOrNull { subInfo -> subInfo.subscriptionId == mSubId } } .flowOn(Dispatchers.Default) .collectLatestWithLifecycle(viewLifecycleOwner) { it?.let { coroutineScope.launch { refreshData(it) } } subscriptionRepository.phoneNumberFlow(mSubId).collectLatestWithLifecycle( viewLifecycleOwner) { phoneNumber -> preference.summary = phoneNumber ?: getStringUnknown() } } @VisibleForTesting suspend fun refreshData(subscriptionInfo: SubscriptionInfo){ withContext(Dispatchers.Default) { phoneNumber = getFormattedPhoneNumber(subscriptionInfo) } refreshUi() } private fun refreshUi(){ preference.summary = phoneNumber } private fun getFormattedPhoneNumber(subscriptionInfo: SubscriptionInfo?): String { val phoneNumber = SubscriptionUtil.getBidiFormattedPhoneNumber( mContext, subscriptionInfo ) return phoneNumber ?.let { return it.ifEmpty { getStringUnknown() } } ?: getStringUnknown() } private fun getStringUnknown(): String { return mContext.getString(R.string.device_info_default) } Loading
src/com/android/settings/network/telephony/MobileNetworkSettings.java +1 −1 Original line number Diff line number Diff line Loading @@ -257,7 +257,7 @@ public class MobileNetworkSettings extends AbstractMobileNetworkSettings impleme use(NrDisabledInDsdsFooterPreferenceController.class).init(mSubId); use(MobileNetworkSpnPreferenceController.class).init(this, mSubId); use(MobileNetworkPhoneNumberPreferenceController.class).init(this, mSubId); use(MobileNetworkPhoneNumberPreferenceController.class).init(mSubId); use(MobileNetworkImeiPreferenceController.class).init(this, mSubId); final MobileDataPreferenceController mobileDataPreferenceController = Loading
src/com/android/settings/network/telephony/SubscriptionRepository.kt +33 −11 Original line number Diff line number Diff line Loading @@ -24,13 +24,14 @@ import androidx.lifecycle.LifecycleOwner import com.android.settings.network.SubscriptionUtil import com.android.settingslib.spa.framework.util.collectLatestWithLifecycle import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.asExecutor import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.callbackFlow import kotlinx.coroutines.flow.conflate import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.filterNot import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.map Loading @@ -52,7 +53,7 @@ class SubscriptionRepository(private val context: Context) { /** Flow of whether the subscription enabled for the given [subId]. */ fun isSubscriptionEnabledFlow(subId: Int): Flow<Boolean> { if (!SubscriptionManager.isValidSubscriptionId(subId)) return flowOf(false) return context.subscriptionsChangedFlow() return subscriptionsChangedFlow() .map { subscriptionManager.isSubscriptionEnabled(subId) } .conflate() .onEach { Log.d(TAG, "[$subId] isSubscriptionEnabledFlow: $it") } Loading Loading @@ -87,12 +88,30 @@ class SubscriptionRepository(private val context: Context) { }.conflate().onEach { Log.d(TAG, "subscriptions changed") }.flowOn(Dispatchers.Default) /** Flow of active subscription ids. */ fun activeSubscriptionIdListFlow(): Flow<List<Int>> = context.subscriptionsChangedFlow() fun activeSubscriptionIdListFlow(): Flow<List<Int>> = subscriptionsChangedFlow() .map { subscriptionManager.activeSubscriptionIdList.sorted() } .distinctUntilChanged() .conflate() .onEach { Log.d(TAG, "activeSubscriptionIdList: $it") } .flowOn(Dispatchers.Default) fun activeSubscriptionInfoFlow(subId: Int): Flow<SubscriptionInfo?> = subscriptionsChangedFlow() .map { subscriptionManager.getActiveSubscriptionInfo(subId) } .distinctUntilChanged() .conflate() .flowOn(Dispatchers.Default) @OptIn(ExperimentalCoroutinesApi::class) fun phoneNumberFlow(subId: Int): Flow<String?> = activeSubscriptionInfoFlow(subId).flatMapLatest { subInfo -> if (subInfo != null) { context.phoneNumberFlow(subInfo) } else { flowOf(null) } } } val Context.subscriptionManager: SubscriptionManager? Loading @@ -100,9 +119,12 @@ val Context.subscriptionManager: SubscriptionManager? fun Context.requireSubscriptionManager(): SubscriptionManager = subscriptionManager!! fun Context.phoneNumberFlow(subscriptionInfo: SubscriptionInfo) = subscriptionsChangedFlow().map { SubscriptionUtil.getBidiFormattedPhoneNumber(this, subscriptionInfo) }.filterNot { it.isNullOrEmpty() }.flowOn(Dispatchers.Default) fun Context.phoneNumberFlow(subscriptionInfo: SubscriptionInfo): Flow<String?> = subscriptionsChangedFlow() .map { SubscriptionUtil.getBidiFormattedPhoneNumber(this, subscriptionInfo) } .distinctUntilChanged() .conflate() .flowOn(Dispatchers.Default) fun Context.subscriptionsChangedFlow(): Flow<Unit> = SubscriptionRepository(this).subscriptionsChangedFlow() Loading
tests/spa_unit/src/com/android/settings/network/telephony/MobileNetworkPhoneNumberPreferenceControllerTest.kt +35 −61 Original line number Diff line number Diff line Loading @@ -17,8 +17,7 @@ package com.android.settings.network.telephony import android.content.Context import android.telephony.SubscriptionInfo import androidx.fragment.app.Fragment import androidx.lifecycle.testing.TestLifecycleOwner import androidx.preference.Preference import androidx.preference.PreferenceManager import androidx.test.core.app.ApplicationProvider Loading @@ -26,17 +25,19 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import com.android.dx.mockito.inline.extended.ExtendedMockito import com.android.settings.R import com.android.settings.core.BasePreferenceController import com.android.settings.network.SubscriptionInfoListViewModel import com.android.settings.network.SubscriptionUtil import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.delay import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.runBlocking import org.junit.After import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.MockitoSession import org.mockito.kotlin.any import org.mockito.kotlin.doReturn import org.mockito.kotlin.mock import org.mockito.kotlin.stub import org.mockito.kotlin.whenever import org.mockito.quality.Strictness Loading @@ -44,29 +45,25 @@ import org.mockito.quality.Strictness class MobileNetworkPhoneNumberPreferenceControllerTest { private lateinit var mockSession: MockitoSession private val mockViewModels = mock<Lazy<SubscriptionInfoListViewModel>>() private val mockFragment = mock<Fragment>{ val viewmodel = mockViewModels } private var mockPhoneNumber = String() private val context: Context = ApplicationProvider.getApplicationContext() private val controller = MobileNetworkPhoneNumberPreferenceController(context, TEST_KEY) private val mockSubscriptionRepository = mock<SubscriptionRepository>() private val controller = MobileNetworkPhoneNumberPreferenceController(context, TEST_KEY, mockSubscriptionRepository) private val preference = Preference(context).apply { key = TEST_KEY } private val preferenceScreen = PreferenceManager(context).createPreferenceScreen(context) @Before fun setUp() { mockSession = ExtendedMockito.mockitoSession() .initMocks(this) mockSession = ExtendedMockito.mockitoSession() .mockStatic(SubscriptionUtil::class.java) .strictness(Strictness.LENIENT) .startMocking() preferenceScreen.addPreference(preference) controller.init(SUB_ID) controller.displayPreference(preferenceScreen) whenever(SubscriptionUtil.getBidiFormattedPhoneNumber(any(),any())).thenReturn(mockPhoneNumber) } @After Loading @@ -75,41 +72,29 @@ class MobileNetworkPhoneNumberPreferenceControllerTest { } @Test fun refreshData_getEmptyPhoneNumber_preferenceIsNotVisible() = runBlocking { fun onViewCreated_cannotGetPhoneNumber_displayUnknown() = runBlocking { whenever(SubscriptionUtil.isSimHardwareVisible(context)).thenReturn(true) whenever(SubscriptionUtil.getActiveSubscriptions(any())).thenReturn( listOf( SUB_INFO_1, SUB_INFO_2 ) ) var mockSubId = 2 controller.init(mockFragment, mockSubId) mockPhoneNumber = String() controller.refreshData(SUB_INFO_2) assertThat(preference.summary).isEqualTo( context.getString(R.string.device_info_default)) mockSubscriptionRepository.stub { on { phoneNumberFlow(SUB_ID) } doReturn flowOf(null) } controller.onViewCreated(TestLifecycleOwner()) delay(100) assertThat(preference.summary).isEqualTo(context.getString(R.string.device_info_default)) } @Test fun refreshData_getPhoneNumber_preferenceSummaryIsExpected() = runBlocking { fun onViewCreated_canGetPhoneNumber_displayPhoneNumber() = runBlocking { whenever(SubscriptionUtil.isSimHardwareVisible(context)).thenReturn(true) whenever(SubscriptionUtil.getActiveSubscriptions(any())).thenReturn( listOf( SUB_INFO_1, SUB_INFO_2 ) ) var mockSubId = 2 controller.init(mockFragment, mockSubId) mockPhoneNumber = "test phone number" whenever(SubscriptionUtil.getBidiFormattedPhoneNumber(any(),any())).thenReturn(mockPhoneNumber) controller.refreshData(SUB_INFO_2) assertThat(preference.summary).isEqualTo(mockPhoneNumber) mockSubscriptionRepository.stub { on { phoneNumberFlow(SUB_ID) } doReturn flowOf(PHONE_NUMBER) } controller.onViewCreated(TestLifecycleOwner()) delay(100) assertThat(preference.summary).isEqualTo(PHONE_NUMBER) } @Test Loading @@ -123,18 +108,7 @@ class MobileNetworkPhoneNumberPreferenceControllerTest { private companion object { const val TEST_KEY = "test_key" const val DISPLAY_NAME_1 = "Sub 1" const val DISPLAY_NAME_2 = "Sub 2" val SUB_INFO_1: SubscriptionInfo = SubscriptionInfo.Builder().apply { setId(1) setDisplayName(DISPLAY_NAME_1) }.build() val SUB_INFO_2: SubscriptionInfo = SubscriptionInfo.Builder().apply { setId(2) setDisplayName(DISPLAY_NAME_2) }.build() const val SUB_ID = 10 const val PHONE_NUMBER = "1234567890" } }
tests/spa_unit/src/com/android/settings/network/telephony/SubscriptionRepositoryTest.kt +16 −0 Original line number Diff line number Diff line Loading @@ -204,6 +204,22 @@ class SubscriptionRepositoryTest { assertThat(phoneNumber).isEqualTo(NUMBER_1) } @Test fun phoneNumberFlow_withSubId() = runBlocking { val subInfo = SubscriptionInfo.Builder().apply { setId(SUB_ID_IN_SLOT_1) setMcc(MCC) }.build() mockSubscriptionManager.stub { on { getActiveSubscriptionInfo(SUB_ID_IN_SLOT_1) } doReturn subInfo on { getPhoneNumber(SUB_ID_IN_SLOT_1) } doReturn NUMBER_1 } val phoneNumber = repository.phoneNumberFlow(SUB_ID_IN_SLOT_1).firstWithTimeoutOrNull() assertThat(phoneNumber).isEqualTo(NUMBER_1) } private companion object { const val SIM_SLOT_INDEX_0 = 0 const val SUB_ID_IN_SLOT_0 = 2 Loading