From b0d09d2ad214ec96e91b01cfb4c47386225cfe77 Mon Sep 17 00:00:00 2001 From: Charlotte Lu Date: Tue, 19 Sep 2023 11:35:44 +0800 Subject: [PATCH] Add SettingsExposedDropdownMenuBox and SwitchPreference. Bug: 298906796 Test: Munual Change-Id: I666c51b79589b9529b623c81c156a545af269e03 --- .../network/apn/ApnEditPageProvider.kt | 60 ++++++++- .../android/settings/network/apn/ApnStatus.kt | 2 +- .../network/apn/ApnEditPageProviderTest.kt | 120 +++++++++++++++++- 3 files changed, 173 insertions(+), 9 deletions(-) diff --git a/src/com/android/settings/network/apn/ApnEditPageProvider.kt b/src/com/android/settings/network/apn/ApnEditPageProvider.kt index 1cca81a0714..756d90f3af3 100644 --- a/src/com/android/settings/network/apn/ApnEditPageProvider.kt +++ b/src/com/android/settings/network/apn/ApnEditPageProvider.kt @@ -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 @@ -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( @@ -71,8 +81,13 @@ object ApnEditPageProvider : SettingsPageProvider { } @Composable -fun ApnPage(apnDataInit: ApnData) { - var apnData by remember { mutableStateOf(apnDataInit) } +fun ApnPage(apnDataCur: MutableState) { + 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), ) { @@ -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), diff --git a/src/com/android/settings/network/apn/ApnStatus.kt b/src/com/android/settings/network/apn/ApnStatus.kt index 78734d02ec6..8a2d6134345 100644 --- a/src/com/android/settings/network/apn/ApnStatus.kt +++ b/src/com/android/settings/network/apn/ApnStatus.kt @@ -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 = "", diff --git a/tests/spa_unit/src/com/android/settings/network/apn/ApnEditPageProviderTest.kt b/tests/spa_unit/src/com/android/settings/network/apn/ApnEditPageProviderTest.kt index bfdb408b0b9..c6c37d58aad 100644 --- a/tests/spa_unit/src/com/android/settings/network/apn/ApnEditPageProviderTest.kt +++ b/tests/spa_unit/src/com/android/settings/network/apn/ApnEditPageProviderTest.kt @@ -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 @@ -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() { @@ -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() } @@ -53,8 +77,94 @@ class ApnEditPageProviderTest { @Test fun name_displayed() { composeTestRule.setContent { - ApnPage(apnData) + ApnPage(remember { + mutableStateOf(apnData) + }) } - composeTestRule.onNodeWithText("apn_name", true).assertIsDisplayed() + 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.onRoot().onChild().onChildAt(0) + .performScrollToNode(hasText(apnEnable, true)) + composeTestRule.onNodeWithText(apnEnable, true).assertIsOn() } } \ No newline at end of file