Loading src/com/android/settings/spa/network/SimOnboardingLabelSim.kt +4 −4 Original line number Diff line number Diff line Loading @@ -56,12 +56,12 @@ fun SimOnboardingLabelSimImpl( imageVector = Icons.Outlined.SignalCellularAlt, title = stringResource(R.string.sim_onboarding_label_sim_title), actionButton = BottomAppBarButton( stringResource(R.string.sim_onboarding_next), nextAction text = stringResource(R.string.sim_onboarding_next), onClick = nextAction ), dismissButton = BottomAppBarButton( stringResource(R.string.cancel), cancelAction text = stringResource(R.string.cancel), onClick = cancelAction ), ) { LabelSimBody(onboardingService) Loading src/com/android/settings/spa/network/SimOnboardingPrimarySim.kt +4 −4 Original line number Diff line number Diff line Loading @@ -59,12 +59,12 @@ fun SimOnboardingPrimarySimImpl( imageVector = Icons.Outlined.SignalCellularAlt, title = stringResource(id = R.string.sim_onboarding_primary_sim_title), actionButton = BottomAppBarButton( stringResource(id = R.string.done), nextAction text = stringResource(id = R.string.done), onClick = nextAction ), dismissButton = BottomAppBarButton( stringResource(id = R.string.cancel), cancelAction text = stringResource(id = R.string.cancel), onClick = cancelAction ), ) { val callsSelectedId = rememberSaveable { Loading src/com/android/settings/spa/network/SimOnboardingSelectSim.kt +15 −13 Original line number Diff line number Diff line Loading @@ -16,12 +16,12 @@ package com.android.settings.spa.network import android.util.Log import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.padding import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.SignalCellularAlt import androidx.compose.runtime.Composable import androidx.compose.runtime.MutableState import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.saveable.rememberSaveable Loading @@ -29,7 +29,6 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import com.android.settings.R import com.android.settings.network.SimOnboardingService import com.android.settings.sim.SimDialogActivity import com.android.settingslib.spa.framework.theme.SettingsDimension import com.android.settingslib.spa.widget.preference.CheckboxPreference import com.android.settingslib.spa.widget.preference.CheckboxPreferenceModel Loading @@ -46,44 +45,47 @@ fun SimOnboardingSelectSimImpl( cancelAction: () -> Unit, onboardingService: SimOnboardingService ) { var actionButtonController = rememberSaveable { mutableStateOf(false) } SuwScaffold( imageVector = Icons.Outlined.SignalCellularAlt, title = stringResource(id = R.string.sim_onboarding_select_sim_title), actionButton = BottomAppBarButton( stringResource(id = R.string.sim_onboarding_next), nextAction text = stringResource(id = R.string.sim_onboarding_next), enabled = actionButtonController.value, onClick = nextAction ), dismissButton = BottomAppBarButton( stringResource(id = R.string.cancel), cancelAction text = stringResource(id = R.string.cancel), onClick = cancelAction ), ) { selectSimBody(onboardingService) SelectSimBody(onboardingService, actionButtonController) } } @Composable private fun selectSimBody(onboardingService: SimOnboardingService) { private fun SelectSimBody( onboardingService: SimOnboardingService, isFinished: MutableState<Boolean> ) { Column(Modifier.padding(SettingsDimension.itemPadding)) { SettingsBody(stringResource(id = R.string.sim_onboarding_select_sim_msg)) } var isFinished = rememberSaveable { mutableStateOf(false) } isFinished.value = onboardingService.isSimSelectionFinished for (subInfo in onboardingService.getSelectableSubscriptionInfoList()) { var title = onboardingService.getSubscriptionInfoDisplayName(subInfo) var summaryNumber = subInfo.number // TODO using the SubscriptionUtil.getFormattedPhoneNumber val phoneNumber = phoneNumber(subInfo) var checked = rememberSaveable { mutableStateOf( onboardingService.getSelectedSubscriptionInfoList().contains(subInfo) ) } CheckboxPreference(remember { object : CheckboxPreferenceModel { override val title = title override val summary: () -> String get() = { summaryNumber } get() = { phoneNumber.value ?: "" } override val checked = { checked.value } override val onCheckedChange = { newChecked: Boolean -> checked.value = newChecked Loading tests/spa_unit/src/com/android/settings/spa/network/SimOnboardingSelectSimTest.kt +61 −7 Original line number Diff line number Diff line Loading @@ -18,19 +18,31 @@ package com.android.settings.spa.network import android.content.Context import android.telephony.SubscriptionInfo import android.telephony.SubscriptionManager import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalLifecycleOwner import androidx.compose.ui.test.assertHasClickAction import androidx.compose.ui.test.assertIsDisplayed import androidx.compose.ui.test.assertIsOn import androidx.compose.ui.test.hasText import androidx.compose.ui.test.junit4.createComposeRule import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.performClick import androidx.lifecycle.testing.TestLifecycleOwner import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.runners.AndroidJUnit4 import com.android.settings.R import com.android.settings.network.SimOnboardingService import com.android.settingslib.spa.testutils.waitUntilExists import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith import org.mockito.kotlin.any import org.mockito.kotlin.doAnswer import org.mockito.kotlin.doReturn import org.mockito.kotlin.mock import org.mockito.kotlin.spy import org.mockito.kotlin.stub import org.mockito.kotlin.verify Loading @@ -38,8 +50,20 @@ import org.mockito.kotlin.verify class SimOnboardingSelectSimTest { @get:Rule val composeTestRule = createComposeRule() private val mockSubscriptionManager = mock<SubscriptionManager> { on { addOnSubscriptionsChangedListener(any(), any()) } doAnswer { val listener = it.arguments[1] as SubscriptionManager.OnSubscriptionsChangedListener listener.onSubscriptionsChanged() } on { getPhoneNumber(SUB_ID_1) } doReturn NUMBER_1 on { getPhoneNumber(SUB_ID_2) } doReturn NUMBER_2 on { getPhoneNumber(SUB_ID_3) } doReturn NUMBER_3 } private val context: Context = spy(ApplicationProvider.getApplicationContext()) { on { getSystemService(SubscriptionManager::class.java) } doReturn mockSubscriptionManager } private val context: Context = ApplicationProvider.getApplicationContext() private var mockSimOnboardingService = mock<SimOnboardingService> { on { targetSubId }.doReturn(-1) on { targetSubInfo }.doReturn(null) Loading Loading @@ -78,6 +102,24 @@ class SimOnboardingSelectSimTest { @Test fun simOnboardingSelectSimImpl_clickNextAction_verifyNextAction() { mockSimOnboardingService.stub { on { targetSubId }.doReturn(SUB_ID_1) on { targetSubInfo }.doReturn(SUB_INFO_1) on { availableSubInfoList }.doReturn(listOf(SUB_INFO_1, SUB_INFO_2, SUB_INFO_3)) on { activeSubInfoList }.doReturn(listOf(SUB_INFO_2, SUB_INFO_3)) on { getSelectableSubscriptionInfoList() }.doReturn( listOf( SUB_INFO_1, SUB_INFO_2, SUB_INFO_3 ) ) on { getSubscriptionInfoDisplayName(SUB_INFO_1) }.doReturn(DISPLAY_NAME_1) on { getSubscriptionInfoDisplayName(SUB_INFO_2) }.doReturn(DISPLAY_NAME_2) on { getSubscriptionInfoDisplayName(SUB_INFO_3) }.doReturn(DISPLAY_NAME_3) on {isSimSelectionFinished}.doReturn(true) } composeTestRule.setContent { SimOnboardingSelectSimImpl(nextAction, cancelAction, mockSimOnboardingService) } Loading @@ -85,7 +127,7 @@ class SimOnboardingSelectSimTest { composeTestRule.onNodeWithText(context.getString(R.string.sim_onboarding_next)) .performClick() verify(nextAction) verify(nextAction)() } @Test Loading @@ -97,7 +139,7 @@ class SimOnboardingSelectSimTest { composeTestRule.onNodeWithText(context.getString(R.string.cancel)) .performClick() verify(cancelAction) verify(cancelAction)() } @Test Loading @@ -120,15 +162,23 @@ class SimOnboardingSelectSimTest { } composeTestRule.setContent { CompositionLocalProvider( LocalContext provides context, LocalLifecycleOwner provides TestLifecycleOwner(), ) { SimOnboardingSelectSimImpl(nextAction, cancelAction, mockSimOnboardingService) } } // composeTestRule.setContent { // SimOnboardingSelectSimImpl(nextAction, cancelAction, mockSimOnboardingService) // } composeTestRule.onNodeWithText(DISPLAY_NAME_1).assertIsDisplayed() composeTestRule.onNodeWithText(NUMBER_1).assertIsDisplayed() composeTestRule.waitUntilExists(hasText(NUMBER_1)) composeTestRule.onNodeWithText(DISPLAY_NAME_2).assertIsDisplayed() composeTestRule.onNodeWithText(NUMBER_2).assertIsDisplayed() composeTestRule.waitUntilExists(hasText(NUMBER_2)) composeTestRule.onNodeWithText(DISPLAY_NAME_3).assertIsDisplayed() composeTestRule.onNodeWithText(NUMBER_3).assertIsDisplayed() composeTestRule.waitUntilExists(hasText(NUMBER_3)) } private companion object { Loading @@ -141,24 +191,28 @@ class SimOnboardingSelectSimTest { const val NUMBER_1 = "000000001" const val NUMBER_2 = "000000002" const val NUMBER_3 = "000000003" const val MCC = "310" const val PRIMARY_SIM_ASK_EVERY_TIME = -1 val SUB_INFO_1: SubscriptionInfo = SubscriptionInfo.Builder().apply { setId(SUB_ID_1) setDisplayName(DISPLAY_NAME_1) setNumber(NUMBER_1) setMcc(MCC) }.build() val SUB_INFO_2: SubscriptionInfo = SubscriptionInfo.Builder().apply { setId(SUB_ID_2) setDisplayName(DISPLAY_NAME_2) setNumber(NUMBER_2) setMcc(MCC) }.build() val SUB_INFO_3: SubscriptionInfo = SubscriptionInfo.Builder().apply { setId(SUB_ID_3) setDisplayName(DISPLAY_NAME_3) setNumber(NUMBER_3) setMcc(MCC) }.build() } } Loading
src/com/android/settings/spa/network/SimOnboardingLabelSim.kt +4 −4 Original line number Diff line number Diff line Loading @@ -56,12 +56,12 @@ fun SimOnboardingLabelSimImpl( imageVector = Icons.Outlined.SignalCellularAlt, title = stringResource(R.string.sim_onboarding_label_sim_title), actionButton = BottomAppBarButton( stringResource(R.string.sim_onboarding_next), nextAction text = stringResource(R.string.sim_onboarding_next), onClick = nextAction ), dismissButton = BottomAppBarButton( stringResource(R.string.cancel), cancelAction text = stringResource(R.string.cancel), onClick = cancelAction ), ) { LabelSimBody(onboardingService) Loading
src/com/android/settings/spa/network/SimOnboardingPrimarySim.kt +4 −4 Original line number Diff line number Diff line Loading @@ -59,12 +59,12 @@ fun SimOnboardingPrimarySimImpl( imageVector = Icons.Outlined.SignalCellularAlt, title = stringResource(id = R.string.sim_onboarding_primary_sim_title), actionButton = BottomAppBarButton( stringResource(id = R.string.done), nextAction text = stringResource(id = R.string.done), onClick = nextAction ), dismissButton = BottomAppBarButton( stringResource(id = R.string.cancel), cancelAction text = stringResource(id = R.string.cancel), onClick = cancelAction ), ) { val callsSelectedId = rememberSaveable { Loading
src/com/android/settings/spa/network/SimOnboardingSelectSim.kt +15 −13 Original line number Diff line number Diff line Loading @@ -16,12 +16,12 @@ package com.android.settings.spa.network import android.util.Log import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.padding import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.SignalCellularAlt import androidx.compose.runtime.Composable import androidx.compose.runtime.MutableState import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.saveable.rememberSaveable Loading @@ -29,7 +29,6 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import com.android.settings.R import com.android.settings.network.SimOnboardingService import com.android.settings.sim.SimDialogActivity import com.android.settingslib.spa.framework.theme.SettingsDimension import com.android.settingslib.spa.widget.preference.CheckboxPreference import com.android.settingslib.spa.widget.preference.CheckboxPreferenceModel Loading @@ -46,44 +45,47 @@ fun SimOnboardingSelectSimImpl( cancelAction: () -> Unit, onboardingService: SimOnboardingService ) { var actionButtonController = rememberSaveable { mutableStateOf(false) } SuwScaffold( imageVector = Icons.Outlined.SignalCellularAlt, title = stringResource(id = R.string.sim_onboarding_select_sim_title), actionButton = BottomAppBarButton( stringResource(id = R.string.sim_onboarding_next), nextAction text = stringResource(id = R.string.sim_onboarding_next), enabled = actionButtonController.value, onClick = nextAction ), dismissButton = BottomAppBarButton( stringResource(id = R.string.cancel), cancelAction text = stringResource(id = R.string.cancel), onClick = cancelAction ), ) { selectSimBody(onboardingService) SelectSimBody(onboardingService, actionButtonController) } } @Composable private fun selectSimBody(onboardingService: SimOnboardingService) { private fun SelectSimBody( onboardingService: SimOnboardingService, isFinished: MutableState<Boolean> ) { Column(Modifier.padding(SettingsDimension.itemPadding)) { SettingsBody(stringResource(id = R.string.sim_onboarding_select_sim_msg)) } var isFinished = rememberSaveable { mutableStateOf(false) } isFinished.value = onboardingService.isSimSelectionFinished for (subInfo in onboardingService.getSelectableSubscriptionInfoList()) { var title = onboardingService.getSubscriptionInfoDisplayName(subInfo) var summaryNumber = subInfo.number // TODO using the SubscriptionUtil.getFormattedPhoneNumber val phoneNumber = phoneNumber(subInfo) var checked = rememberSaveable { mutableStateOf( onboardingService.getSelectedSubscriptionInfoList().contains(subInfo) ) } CheckboxPreference(remember { object : CheckboxPreferenceModel { override val title = title override val summary: () -> String get() = { summaryNumber } get() = { phoneNumber.value ?: "" } override val checked = { checked.value } override val onCheckedChange = { newChecked: Boolean -> checked.value = newChecked Loading
tests/spa_unit/src/com/android/settings/spa/network/SimOnboardingSelectSimTest.kt +61 −7 Original line number Diff line number Diff line Loading @@ -18,19 +18,31 @@ package com.android.settings.spa.network import android.content.Context import android.telephony.SubscriptionInfo import android.telephony.SubscriptionManager import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalLifecycleOwner import androidx.compose.ui.test.assertHasClickAction import androidx.compose.ui.test.assertIsDisplayed import androidx.compose.ui.test.assertIsOn import androidx.compose.ui.test.hasText import androidx.compose.ui.test.junit4.createComposeRule import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.performClick import androidx.lifecycle.testing.TestLifecycleOwner import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.runners.AndroidJUnit4 import com.android.settings.R import com.android.settings.network.SimOnboardingService import com.android.settingslib.spa.testutils.waitUntilExists import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith import org.mockito.kotlin.any import org.mockito.kotlin.doAnswer import org.mockito.kotlin.doReturn import org.mockito.kotlin.mock import org.mockito.kotlin.spy import org.mockito.kotlin.stub import org.mockito.kotlin.verify Loading @@ -38,8 +50,20 @@ import org.mockito.kotlin.verify class SimOnboardingSelectSimTest { @get:Rule val composeTestRule = createComposeRule() private val mockSubscriptionManager = mock<SubscriptionManager> { on { addOnSubscriptionsChangedListener(any(), any()) } doAnswer { val listener = it.arguments[1] as SubscriptionManager.OnSubscriptionsChangedListener listener.onSubscriptionsChanged() } on { getPhoneNumber(SUB_ID_1) } doReturn NUMBER_1 on { getPhoneNumber(SUB_ID_2) } doReturn NUMBER_2 on { getPhoneNumber(SUB_ID_3) } doReturn NUMBER_3 } private val context: Context = spy(ApplicationProvider.getApplicationContext()) { on { getSystemService(SubscriptionManager::class.java) } doReturn mockSubscriptionManager } private val context: Context = ApplicationProvider.getApplicationContext() private var mockSimOnboardingService = mock<SimOnboardingService> { on { targetSubId }.doReturn(-1) on { targetSubInfo }.doReturn(null) Loading Loading @@ -78,6 +102,24 @@ class SimOnboardingSelectSimTest { @Test fun simOnboardingSelectSimImpl_clickNextAction_verifyNextAction() { mockSimOnboardingService.stub { on { targetSubId }.doReturn(SUB_ID_1) on { targetSubInfo }.doReturn(SUB_INFO_1) on { availableSubInfoList }.doReturn(listOf(SUB_INFO_1, SUB_INFO_2, SUB_INFO_3)) on { activeSubInfoList }.doReturn(listOf(SUB_INFO_2, SUB_INFO_3)) on { getSelectableSubscriptionInfoList() }.doReturn( listOf( SUB_INFO_1, SUB_INFO_2, SUB_INFO_3 ) ) on { getSubscriptionInfoDisplayName(SUB_INFO_1) }.doReturn(DISPLAY_NAME_1) on { getSubscriptionInfoDisplayName(SUB_INFO_2) }.doReturn(DISPLAY_NAME_2) on { getSubscriptionInfoDisplayName(SUB_INFO_3) }.doReturn(DISPLAY_NAME_3) on {isSimSelectionFinished}.doReturn(true) } composeTestRule.setContent { SimOnboardingSelectSimImpl(nextAction, cancelAction, mockSimOnboardingService) } Loading @@ -85,7 +127,7 @@ class SimOnboardingSelectSimTest { composeTestRule.onNodeWithText(context.getString(R.string.sim_onboarding_next)) .performClick() verify(nextAction) verify(nextAction)() } @Test Loading @@ -97,7 +139,7 @@ class SimOnboardingSelectSimTest { composeTestRule.onNodeWithText(context.getString(R.string.cancel)) .performClick() verify(cancelAction) verify(cancelAction)() } @Test Loading @@ -120,15 +162,23 @@ class SimOnboardingSelectSimTest { } composeTestRule.setContent { CompositionLocalProvider( LocalContext provides context, LocalLifecycleOwner provides TestLifecycleOwner(), ) { SimOnboardingSelectSimImpl(nextAction, cancelAction, mockSimOnboardingService) } } // composeTestRule.setContent { // SimOnboardingSelectSimImpl(nextAction, cancelAction, mockSimOnboardingService) // } composeTestRule.onNodeWithText(DISPLAY_NAME_1).assertIsDisplayed() composeTestRule.onNodeWithText(NUMBER_1).assertIsDisplayed() composeTestRule.waitUntilExists(hasText(NUMBER_1)) composeTestRule.onNodeWithText(DISPLAY_NAME_2).assertIsDisplayed() composeTestRule.onNodeWithText(NUMBER_2).assertIsDisplayed() composeTestRule.waitUntilExists(hasText(NUMBER_2)) composeTestRule.onNodeWithText(DISPLAY_NAME_3).assertIsDisplayed() composeTestRule.onNodeWithText(NUMBER_3).assertIsDisplayed() composeTestRule.waitUntilExists(hasText(NUMBER_3)) } private companion object { Loading @@ -141,24 +191,28 @@ class SimOnboardingSelectSimTest { const val NUMBER_1 = "000000001" const val NUMBER_2 = "000000002" const val NUMBER_3 = "000000003" const val MCC = "310" const val PRIMARY_SIM_ASK_EVERY_TIME = -1 val SUB_INFO_1: SubscriptionInfo = SubscriptionInfo.Builder().apply { setId(SUB_ID_1) setDisplayName(DISPLAY_NAME_1) setNumber(NUMBER_1) setMcc(MCC) }.build() val SUB_INFO_2: SubscriptionInfo = SubscriptionInfo.Builder().apply { setId(SUB_ID_2) setDisplayName(DISPLAY_NAME_2) setNumber(NUMBER_2) setMcc(MCC) }.build() val SUB_INFO_3: SubscriptionInfo = SubscriptionInfo.Builder().apply { setId(SUB_ID_3) setDisplayName(DISPLAY_NAME_3) setNumber(NUMBER_3) setMcc(MCC) }.build() } }