Add SettingsExposedDropdownMenuBox and SwitchPreference.

Bug: 298906796
Test: Munual
Change-Id: I666c51b79589b9529b623c81c156a545af269e03
This commit is contained in:
Charlotte Lu
2023-09-19 11:35:44 +08:00
parent 4964deb8b5
commit b0d09d2ad2
3 changed files with 173 additions and 9 deletions

View File

@@ -20,16 +20,23 @@ import android.net.Uri
import android.os.Bundle import android.os.Bundle
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue 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.compose.ui.res.stringResource
import androidx.navigation.NavType import androidx.navigation.NavType
import androidx.navigation.navArgument import androidx.navigation.navArgument
import com.android.settings.R import com.android.settings.R
import com.android.settingslib.spa.framework.common.SettingsPageProvider 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.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 com.android.settingslib.spa.widget.scaffold.RegularScaffold
import java.util.Base64 import java.util.Base64
@@ -56,7 +63,10 @@ object ApnEditPageProvider : SettingsPageProvider {
@Composable @Composable
override fun Page(arguments: Bundle?) { override fun Page(arguments: Bundle?) {
val apnDataInit = ApnData() val apnDataInit = ApnData()
ApnPage(apnDataInit) val apnDataCur = remember {
mutableStateOf(apnDataInit)
}
ApnPage(apnDataCur)
} }
fun getRoute( fun getRoute(
@@ -71,8 +81,13 @@ object ApnEditPageProvider : SettingsPageProvider {
} }
@Composable @Composable
fun ApnPage(apnDataInit: ApnData) { fun ApnPage(apnDataCur: MutableState<ApnData>) {
var apnData by remember { mutableStateOf(apnDataInit) } 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( RegularScaffold(
title = stringResource(id = R.string.apn_edit), title = stringResource(id = R.string.apn_edit),
) { ) {
@@ -133,11 +148,50 @@ fun ApnPage(apnDataInit: ApnData) {
stringResource(R.string.apn_mnc), stringResource(R.string.apn_mnc),
enabled = apnData.mncEnabled enabled = apnData.mncEnabled
) { apnData = apnData.copy(mnc = it) } ) { 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( SettingsOutlinedTextField(
apnData.apnType, apnData.apnType,
stringResource(R.string.apn_type), stringResource(R.string.apn_type),
enabled = apnData.apnTypeEnabled enabled = apnData.apnTypeEnabled
) { apnData = apnData.copy(apn = it) } // TODO: updateApnType ) { 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( SettingsOutlinedTextField(
apnData.mvnoValue, apnData.mvnoValue,
stringResource(R.string.mvno_match_data), stringResource(R.string.mvno_match_data),

View File

@@ -36,7 +36,7 @@ data class ApnData(
val apnType: String = "", val apnType: String = "",
val apnProtocol: String = "", val apnProtocol: String = "",
val apnRoaming: String = "", val apnRoaming: String = "",
val apnEnable: Int = 1, val apnEnable: Boolean = true,
val bearer: Int = 0, val bearer: Int = 0,
val mvnoType: String = "", val mvnoType: String = "",
var mvnoValue: String = "", var mvnoValue: String = "",

View File

@@ -17,9 +17,17 @@
package com.android.settings.network.apn package com.android.settings.network.apn
import android.content.Context 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.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.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.onNodeWithText
import androidx.compose.ui.test.onRoot
import androidx.compose.ui.test.performScrollToNode
import androidx.test.core.app.ApplicationProvider import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.ext.junit.runners.AndroidJUnit4
import com.android.settings.R import com.android.settings.R
@@ -34,8 +42,22 @@ class ApnEditPageProviderTest {
val composeTestRule = createComposeRule() val composeTestRule = createComposeRule()
private val context: Context = ApplicationProvider.getApplicationContext() private val context: Context = ApplicationProvider.getApplicationContext()
private val apnName = "apn_name"
val apnData = ApnData(name = "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 @Test
fun apnEditPageProvider_name() { fun apnEditPageProvider_name() {
@@ -45,7 +67,9 @@ class ApnEditPageProviderTest {
@Test @Test
fun title_displayed() { fun title_displayed() {
composeTestRule.setContent { composeTestRule.setContent {
ApnPage(apnData) ApnPage(remember {
mutableStateOf(apnData)
})
} }
composeTestRule.onNodeWithText(context.getString(R.string.apn_edit)).assertIsDisplayed() composeTestRule.onNodeWithText(context.getString(R.string.apn_edit)).assertIsDisplayed()
} }
@@ -53,8 +77,94 @@ class ApnEditPageProviderTest {
@Test @Test
fun name_displayed() { fun name_displayed() {
composeTestRule.setContent { 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()
} }
} }