Loading src/com/android/settings/network/apn/ApnEditPageProvider.kt +57 −3 Original line number Diff line number Diff line Loading @@ -20,16 +20,23 @@ import android.net.Uri import android.os.Bundle import androidx.compose.foundation.layout.Column import androidx.compose.runtime.Composable import androidx.compose.runtime.MutableState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringArrayResource import androidx.compose.ui.res.stringResource import androidx.navigation.NavType import androidx.navigation.navArgument import com.android.settings.R import com.android.settingslib.spa.framework.common.SettingsPageProvider import com.android.settingslib.spa.framework.compose.stateOf import com.android.settingslib.spa.widget.editor.SettingsExposedDropdownMenuBox import com.android.settingslib.spa.widget.editor.SettingsOutlinedTextField import com.android.settingslib.spa.widget.preference.SwitchPreference import com.android.settingslib.spa.widget.preference.SwitchPreferenceModel import com.android.settingslib.spa.widget.scaffold.RegularScaffold import java.util.Base64 Loading @@ -56,7 +63,10 @@ object ApnEditPageProvider : SettingsPageProvider { @Composable override fun Page(arguments: Bundle?) { val apnDataInit = ApnData() ApnPage(apnDataInit) val apnDataCur = remember { mutableStateOf(apnDataInit) } ApnPage(apnDataCur) } fun getRoute( Loading @@ -71,8 +81,13 @@ object ApnEditPageProvider : SettingsPageProvider { } @Composable fun ApnPage(apnDataInit: ApnData) { var apnData by remember { mutableStateOf(apnDataInit) } fun ApnPage(apnDataCur: MutableState<ApnData>) { var apnData by apnDataCur val context = LocalContext.current val authTypeOptions = stringArrayResource(R.array.apn_auth_entries).toList() val apnProtocolOptions = stringArrayResource(R.array.apn_protocol_entries).toList() val mvnoTypeOptions = stringArrayResource(R.array.mvno_type_entries).toList() RegularScaffold( title = stringResource(id = R.string.apn_edit), ) { Loading Loading @@ -133,11 +148,50 @@ fun ApnPage(apnDataInit: ApnData) { stringResource(R.string.apn_mnc), enabled = apnData.mncEnabled ) { apnData = apnData.copy(mnc = it) } SettingsExposedDropdownMenuBox( label = stringResource(R.string.apn_auth_type), options = authTypeOptions, selectedOptionText = authTypeOptions.getOrElse(apnData.authType) { "" }, enabled = apnData.authTypeEnabled, ) { apnData = apnData.copy(authType = authTypeOptions.indexOf(it)) } SettingsOutlinedTextField( apnData.apnType, stringResource(R.string.apn_type), enabled = apnData.apnTypeEnabled ) { apnData = apnData.copy(apn = it) } // TODO: updateApnType SettingsExposedDropdownMenuBox( stringResource(R.string.apn_protocol), apnProtocolOptions, apnData.apnProtocol, apnData.apnProtocolEnabled ) { apnData = apnData.copy(apnProtocol = it) } SettingsExposedDropdownMenuBox( stringResource(R.string.apn_roaming_protocol), apnProtocolOptions, apnData.apnRoaming, apnData.apnRoamingEnabled ) { apnData = apnData.copy(apnRoaming = it) } SwitchPreference( object : SwitchPreferenceModel { override val title = context.resources.getString(R.string.carrier_enabled) override val changeable = stateOf(apnData.apnEnableEnabled) override val checked = stateOf(apnData.apnEnable) override val onCheckedChange = { newChecked: Boolean -> apnData = apnData.copy(apnEnable = newChecked) } } ) SettingsExposedDropdownMenuBox( stringResource(R.string.mvno_type), mvnoTypeOptions, apnData.mvnoType, apnData.mvnoTypeEnabled ) { apnData = apnData.copy(mvnoType = it) } // TODO: mvnoDescription SettingsOutlinedTextField( apnData.mvnoValue, stringResource(R.string.mvno_match_data), Loading src/com/android/settings/network/apn/ApnStatus.kt +1 −1 Original line number Diff line number Diff line Loading @@ -36,7 +36,7 @@ data class ApnData( val apnType: String = "", val apnProtocol: String = "", val apnRoaming: String = "", val apnEnable: Int = 1, val apnEnable: Boolean = true, val bearer: Int = 0, val mvnoType: String = "", var mvnoValue: String = "", Loading tests/spa_unit/src/com/android/settings/network/apn/ApnEditPageProviderTest.kt +115 −5 Original line number Diff line number Diff line Loading @@ -17,9 +17,17 @@ package com.android.settings.network.apn import android.content.Context import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember 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.onChild import androidx.compose.ui.test.onChildAt import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.onRoot import androidx.compose.ui.test.performScrollToNode import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.runners.AndroidJUnit4 import com.android.settings.R Loading @@ -34,8 +42,22 @@ class ApnEditPageProviderTest { val composeTestRule = createComposeRule() private val context: Context = ApplicationProvider.getApplicationContext() val apnData = ApnData(name = "apn_name") private val apnName = "apn_name" private val mmsc = "mmsc" private val mmsProxy = "mms_proxy" private val mnc = "mnc" private val apnType = "apn_type" private val apnRoaming = "IPv4" private val apnEnable = context.resources.getString(R.string.carrier_enabled) private val apnData = ApnData( name = apnName, mmsc = mmsc, mmsProxy = mmsProxy, mnc = mnc, apnType = apnType, apnRoaming = apnRoaming, apnEnable = true ) @Test fun apnEditPageProvider_name() { Loading @@ -45,7 +67,9 @@ class ApnEditPageProviderTest { @Test fun title_displayed() { composeTestRule.setContent { ApnPage(apnData) ApnPage(remember { mutableStateOf(apnData) }) } composeTestRule.onNodeWithText(context.getString(R.string.apn_edit)).assertIsDisplayed() } Loading @@ -53,8 +77,94 @@ class ApnEditPageProviderTest { @Test fun name_displayed() { composeTestRule.setContent { ApnPage(apnData) ApnPage(remember { mutableStateOf(apnData) }) } composeTestRule.onNodeWithText(apnName, true).assertIsDisplayed() } @Test fun mmsc_displayed() { composeTestRule.setContent { ApnPage(remember { mutableStateOf(apnData) }) } composeTestRule.onRoot().onChild().onChildAt(0) .performScrollToNode(hasText(mmsc, true)) composeTestRule.onNodeWithText(mmsc, true).assertIsDisplayed() } @Test fun mms_proxy_displayed() { composeTestRule.setContent { ApnPage(remember { mutableStateOf(apnData) }) } composeTestRule.onRoot().onChild().onChildAt(0) .performScrollToNode(hasText(mmsProxy, true)) composeTestRule.onNodeWithText(mmsProxy, true).assertIsDisplayed() } @Test fun mnc_displayed() { composeTestRule.setContent { ApnPage(remember { mutableStateOf(apnData) }) } composeTestRule.onRoot().onChild().onChildAt(0) .performScrollToNode(hasText(mnc, true)) composeTestRule.onNodeWithText(mnc, true).assertIsDisplayed() } @Test fun apn_type_displayed() { composeTestRule.setContent { ApnPage(remember { mutableStateOf(apnData) }) } composeTestRule.onRoot().onChild().onChildAt(0) .performScrollToNode(hasText(apnType, true)) composeTestRule.onNodeWithText(apnType, true).assertIsDisplayed() } @Test fun apn_roaming_displayed() { composeTestRule.setContent { ApnPage(remember { mutableStateOf(apnData) }) } composeTestRule.onRoot().onChild().onChildAt(0) .performScrollToNode(hasText(apnRoaming, true)) composeTestRule.onNodeWithText(apnRoaming, true).assertIsDisplayed() } @Test fun carrier_enabled_displayed() { composeTestRule.setContent { ApnPage(remember { mutableStateOf(apnData) }) } composeTestRule.onRoot().onChild().onChildAt(0) .performScrollToNode(hasText(apnEnable, true)) composeTestRule.onNodeWithText(apnEnable, true).assertIsDisplayed() } @Test fun carrier_enabled_isChecked() { composeTestRule.setContent { ApnPage(remember { mutableStateOf(apnData) }) } composeTestRule.onNodeWithText("apn_name", true).assertIsDisplayed() composeTestRule.onRoot().onChild().onChildAt(0) .performScrollToNode(hasText(apnEnable, true)) composeTestRule.onNodeWithText(apnEnable, true).assertIsOn() } } No newline at end of file Loading
src/com/android/settings/network/apn/ApnEditPageProvider.kt +57 −3 Original line number Diff line number Diff line Loading @@ -20,16 +20,23 @@ import android.net.Uri import android.os.Bundle import androidx.compose.foundation.layout.Column import androidx.compose.runtime.Composable import androidx.compose.runtime.MutableState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringArrayResource import androidx.compose.ui.res.stringResource import androidx.navigation.NavType import androidx.navigation.navArgument import com.android.settings.R import com.android.settingslib.spa.framework.common.SettingsPageProvider import com.android.settingslib.spa.framework.compose.stateOf import com.android.settingslib.spa.widget.editor.SettingsExposedDropdownMenuBox import com.android.settingslib.spa.widget.editor.SettingsOutlinedTextField import com.android.settingslib.spa.widget.preference.SwitchPreference import com.android.settingslib.spa.widget.preference.SwitchPreferenceModel import com.android.settingslib.spa.widget.scaffold.RegularScaffold import java.util.Base64 Loading @@ -56,7 +63,10 @@ object ApnEditPageProvider : SettingsPageProvider { @Composable override fun Page(arguments: Bundle?) { val apnDataInit = ApnData() ApnPage(apnDataInit) val apnDataCur = remember { mutableStateOf(apnDataInit) } ApnPage(apnDataCur) } fun getRoute( Loading @@ -71,8 +81,13 @@ object ApnEditPageProvider : SettingsPageProvider { } @Composable fun ApnPage(apnDataInit: ApnData) { var apnData by remember { mutableStateOf(apnDataInit) } fun ApnPage(apnDataCur: MutableState<ApnData>) { var apnData by apnDataCur val context = LocalContext.current val authTypeOptions = stringArrayResource(R.array.apn_auth_entries).toList() val apnProtocolOptions = stringArrayResource(R.array.apn_protocol_entries).toList() val mvnoTypeOptions = stringArrayResource(R.array.mvno_type_entries).toList() RegularScaffold( title = stringResource(id = R.string.apn_edit), ) { Loading Loading @@ -133,11 +148,50 @@ fun ApnPage(apnDataInit: ApnData) { stringResource(R.string.apn_mnc), enabled = apnData.mncEnabled ) { apnData = apnData.copy(mnc = it) } SettingsExposedDropdownMenuBox( label = stringResource(R.string.apn_auth_type), options = authTypeOptions, selectedOptionText = authTypeOptions.getOrElse(apnData.authType) { "" }, enabled = apnData.authTypeEnabled, ) { apnData = apnData.copy(authType = authTypeOptions.indexOf(it)) } SettingsOutlinedTextField( apnData.apnType, stringResource(R.string.apn_type), enabled = apnData.apnTypeEnabled ) { apnData = apnData.copy(apn = it) } // TODO: updateApnType SettingsExposedDropdownMenuBox( stringResource(R.string.apn_protocol), apnProtocolOptions, apnData.apnProtocol, apnData.apnProtocolEnabled ) { apnData = apnData.copy(apnProtocol = it) } SettingsExposedDropdownMenuBox( stringResource(R.string.apn_roaming_protocol), apnProtocolOptions, apnData.apnRoaming, apnData.apnRoamingEnabled ) { apnData = apnData.copy(apnRoaming = it) } SwitchPreference( object : SwitchPreferenceModel { override val title = context.resources.getString(R.string.carrier_enabled) override val changeable = stateOf(apnData.apnEnableEnabled) override val checked = stateOf(apnData.apnEnable) override val onCheckedChange = { newChecked: Boolean -> apnData = apnData.copy(apnEnable = newChecked) } } ) SettingsExposedDropdownMenuBox( stringResource(R.string.mvno_type), mvnoTypeOptions, apnData.mvnoType, apnData.mvnoTypeEnabled ) { apnData = apnData.copy(mvnoType = it) } // TODO: mvnoDescription SettingsOutlinedTextField( apnData.mvnoValue, stringResource(R.string.mvno_match_data), Loading
src/com/android/settings/network/apn/ApnStatus.kt +1 −1 Original line number Diff line number Diff line Loading @@ -36,7 +36,7 @@ data class ApnData( val apnType: String = "", val apnProtocol: String = "", val apnRoaming: String = "", val apnEnable: Int = 1, val apnEnable: Boolean = true, val bearer: Int = 0, val mvnoType: String = "", var mvnoValue: String = "", Loading
tests/spa_unit/src/com/android/settings/network/apn/ApnEditPageProviderTest.kt +115 −5 Original line number Diff line number Diff line Loading @@ -17,9 +17,17 @@ package com.android.settings.network.apn import android.content.Context import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember 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.onChild import androidx.compose.ui.test.onChildAt import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.onRoot import androidx.compose.ui.test.performScrollToNode import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.runners.AndroidJUnit4 import com.android.settings.R Loading @@ -34,8 +42,22 @@ class ApnEditPageProviderTest { val composeTestRule = createComposeRule() private val context: Context = ApplicationProvider.getApplicationContext() val apnData = ApnData(name = "apn_name") private val apnName = "apn_name" private val mmsc = "mmsc" private val mmsProxy = "mms_proxy" private val mnc = "mnc" private val apnType = "apn_type" private val apnRoaming = "IPv4" private val apnEnable = context.resources.getString(R.string.carrier_enabled) private val apnData = ApnData( name = apnName, mmsc = mmsc, mmsProxy = mmsProxy, mnc = mnc, apnType = apnType, apnRoaming = apnRoaming, apnEnable = true ) @Test fun apnEditPageProvider_name() { Loading @@ -45,7 +67,9 @@ class ApnEditPageProviderTest { @Test fun title_displayed() { composeTestRule.setContent { ApnPage(apnData) ApnPage(remember { mutableStateOf(apnData) }) } composeTestRule.onNodeWithText(context.getString(R.string.apn_edit)).assertIsDisplayed() } Loading @@ -53,8 +77,94 @@ class ApnEditPageProviderTest { @Test fun name_displayed() { composeTestRule.setContent { ApnPage(apnData) ApnPage(remember { mutableStateOf(apnData) }) } composeTestRule.onNodeWithText(apnName, true).assertIsDisplayed() } @Test fun mmsc_displayed() { composeTestRule.setContent { ApnPage(remember { mutableStateOf(apnData) }) } composeTestRule.onRoot().onChild().onChildAt(0) .performScrollToNode(hasText(mmsc, true)) composeTestRule.onNodeWithText(mmsc, true).assertIsDisplayed() } @Test fun mms_proxy_displayed() { composeTestRule.setContent { ApnPage(remember { mutableStateOf(apnData) }) } composeTestRule.onRoot().onChild().onChildAt(0) .performScrollToNode(hasText(mmsProxy, true)) composeTestRule.onNodeWithText(mmsProxy, true).assertIsDisplayed() } @Test fun mnc_displayed() { composeTestRule.setContent { ApnPage(remember { mutableStateOf(apnData) }) } composeTestRule.onRoot().onChild().onChildAt(0) .performScrollToNode(hasText(mnc, true)) composeTestRule.onNodeWithText(mnc, true).assertIsDisplayed() } @Test fun apn_type_displayed() { composeTestRule.setContent { ApnPage(remember { mutableStateOf(apnData) }) } composeTestRule.onRoot().onChild().onChildAt(0) .performScrollToNode(hasText(apnType, true)) composeTestRule.onNodeWithText(apnType, true).assertIsDisplayed() } @Test fun apn_roaming_displayed() { composeTestRule.setContent { ApnPage(remember { mutableStateOf(apnData) }) } composeTestRule.onRoot().onChild().onChildAt(0) .performScrollToNode(hasText(apnRoaming, true)) composeTestRule.onNodeWithText(apnRoaming, true).assertIsDisplayed() } @Test fun carrier_enabled_displayed() { composeTestRule.setContent { ApnPage(remember { mutableStateOf(apnData) }) } composeTestRule.onRoot().onChild().onChildAt(0) .performScrollToNode(hasText(apnEnable, true)) composeTestRule.onNodeWithText(apnEnable, true).assertIsDisplayed() } @Test fun carrier_enabled_isChecked() { composeTestRule.setContent { ApnPage(remember { mutableStateOf(apnData) }) } composeTestRule.onNodeWithText("apn_name", true).assertIsDisplayed() composeTestRule.onRoot().onChild().onChildAt(0) .performScrollToNode(hasText(apnEnable, true)) composeTestRule.onNodeWithText(apnEnable, true).assertIsOn() } } No newline at end of file