From 4188a571aa7e17ba8492d83707e20693b73ea7f9 Mon Sep 17 00:00:00 2001 From: Chaohui Wang Date: Sun, 8 Oct 2023 14:23:37 +0800 Subject: [PATCH] Use network type enum for APN Instead of hardcoded names and values. Bug: 303971237 Test: unit test Change-Id: I099a408df7ee35abc886ed5c1d2d09fd31fda7d3 --- res/values/arrays.xml | 55 ----------------- res/values/strings.xml | 2 + .../network/apn/ApnEditPageProvider.kt | 15 +++-- .../settings/network/apn/ApnNetworkTypes.kt | 59 +++++++++++++++++++ .../android/settings/network/apn/ApnStatus.kt | 35 +---------- .../network/apn/ApnEditPageProviderTest.kt | 31 ++++++---- 6 files changed, 88 insertions(+), 109 deletions(-) create mode 100644 src/com/android/settings/network/apn/ApnNetworkTypes.kt diff --git a/res/values/arrays.xml b/res/values/arrays.xml index 18f37bf8e47..01a8126a3e3 100644 --- a/res/values/arrays.xml +++ b/res/values/arrays.xml @@ -416,61 +416,6 @@ 20 - - - Unspecified - LTE - HSPAP - HSPA - HSUPA - HSDPA - UMTS - EDGE - GPRS - eHRPD - EVDO_B - EVDO_A - EVDO_0 - 1xRTT - CDMA - NR - - - - - 0 - - 13 - - 15 - - 10 - - 9 - - 8 - - 3 - - 2 - - 1 - - 14 - - 12 - - 6 - - 5 - - 7 - - 4 - - 20 - - None diff --git a/res/values/strings.xml b/res/values/strings.xml index 7e6de11b2f6..b50f7fd72e7 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -3123,6 +3123,8 @@ Bearer Network type + + Unspecified MVNO type diff --git a/src/com/android/settings/network/apn/ApnEditPageProvider.kt b/src/com/android/settings/network/apn/ApnEditPageProvider.kt index 97d001c5802..7ffa0c920d4 100644 --- a/src/com/android/settings/network/apn/ApnEditPageProvider.kt +++ b/src/com/android/settings/network/apn/ApnEditPageProvider.kt @@ -31,6 +31,8 @@ import androidx.compose.ui.res.stringResource import androidx.navigation.NavType import androidx.navigation.navArgument import com.android.settings.R +import com.android.settings.network.apn.ApnNetworkTypes.getNetworkTypeDisplayNames +import com.android.settings.network.apn.ApnNetworkTypes.getNetworkTypeSelectedOptionsState import com.android.settingslib.spa.framework.common.SettingsPageProvider import com.android.settingslib.spa.framework.compose.stateOf import com.android.settingslib.spa.widget.editor.SettingsExposedDropdownMenuBox @@ -51,8 +53,8 @@ const val EDIT_URL = "editUrl" object ApnEditPageProvider : SettingsPageProvider { - override val name = "Apn" - const val TAG = "ApnPageProvider" + override val name = "ApnEdit" + const val TAG = "ApnEditPageProvider" override val parameter = listOf( navArgument(URI_TYPE) { type = NavType.StringType }, @@ -88,12 +90,9 @@ fun ApnPage(apnDataCur: MutableState) { val context = LocalContext.current val authTypeOptions = stringArrayResource(R.array.apn_auth_entries).toList() val apnProtocolOptions = stringArrayResource(R.array.apn_protocol_entries).toList() - val networkTypeOptionsAll = stringArrayResource(R.array.network_type_entries) - val networkTypeOptions = networkTypeOptionsAll.drop(1).toList() - val networkTypeEmptyVal = networkTypeOptionsAll[0] val mvnoTypeOptions = stringArrayResource(R.array.mvno_type_entries).toList() val networkTypeSelectedOptionsState = remember { - getNetworkTypeSelectedOptionsState(apnData.networkType, context) + getNetworkTypeSelectedOptionsState(apnData.networkType) } RegularScaffold( title = stringResource(id = R.string.apn_edit), @@ -197,9 +196,9 @@ fun ApnPage(apnDataCur: MutableState) { ) SettingsExposedDropdownMenuCheckBox( label = stringResource(R.string.network_type), - options = networkTypeOptions, + options = getNetworkTypeDisplayNames(), selectedOptionsState = networkTypeSelectedOptionsState, - emptyVal = networkTypeEmptyVal, + emptyVal = stringResource(R.string.network_type_unspecified), enabled = apnData.networkTypeEnabled ) {} SettingsExposedDropdownMenuBox( diff --git a/src/com/android/settings/network/apn/ApnNetworkTypes.kt b/src/com/android/settings/network/apn/ApnNetworkTypes.kt new file mode 100644 index 00000000000..560449a70f8 --- /dev/null +++ b/src/com/android/settings/network/apn/ApnNetworkTypes.kt @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.network.apn + +import android.telephony.TelephonyManager +import androidx.compose.runtime.mutableStateListOf +import androidx.compose.runtime.snapshots.SnapshotStateList + +object ApnNetworkTypes { + private val Types = listOf( + TelephonyManager.NETWORK_TYPE_LTE, + TelephonyManager.NETWORK_TYPE_HSPAP, + TelephonyManager.NETWORK_TYPE_HSPA, + TelephonyManager.NETWORK_TYPE_HSUPA, + TelephonyManager.NETWORK_TYPE_HSDPA, + TelephonyManager.NETWORK_TYPE_UMTS, + TelephonyManager.NETWORK_TYPE_EDGE, + TelephonyManager.NETWORK_TYPE_GPRS, + TelephonyManager.NETWORK_TYPE_EHRPD, + TelephonyManager.NETWORK_TYPE_EVDO_B, + TelephonyManager.NETWORK_TYPE_EVDO_A, + TelephonyManager.NETWORK_TYPE_EVDO_0, + TelephonyManager.NETWORK_TYPE_1xRTT, + TelephonyManager.NETWORK_TYPE_CDMA, + TelephonyManager.NETWORK_TYPE_NR, + ) + + fun getNetworkTypeDisplayNames(): List = + Types.map { TelephonyManager.getNetworkTypeName(it) } + + /** + * Gets the selected Network type Selected Options according to network type. + * @param networkType Initialized network type bitmask, often multiple network type options may + * be included. + */ + fun getNetworkTypeSelectedOptionsState(networkType: Long): SnapshotStateList { + val networkTypeSelectedOptionsState = mutableStateListOf() + Types.forEachIndexed { index, type -> + if (networkType and TelephonyManager.getBitMaskForNetworkType(type) == 1L) { + networkTypeSelectedOptionsState.add(index) + } + } + return networkTypeSelectedOptionsState + } +} diff --git a/src/com/android/settings/network/apn/ApnStatus.kt b/src/com/android/settings/network/apn/ApnStatus.kt index 5a13edeb8dd..c8d1b83c455 100644 --- a/src/com/android/settings/network/apn/ApnStatus.kt +++ b/src/com/android/settings/network/apn/ApnStatus.kt @@ -16,12 +16,8 @@ package com.android.settings.network.apn -import android.content.Context import android.provider.Telephony import android.telephony.TelephonyManager -import androidx.compose.runtime.mutableStateListOf -import androidx.compose.runtime.snapshots.SnapshotStateList -import com.android.settings.R data class ApnData( val name: String = "", @@ -41,7 +37,7 @@ data class ApnData( val apnProtocol: Int = -1, val apnRoaming: Int = -1, val apnEnable: Boolean = true, - val networkType: Int = 0, + val networkType: Long = 0, val mvnoType: Int = -1, var mvnoValue: String = "", val edited: Int = Telephony.Carriers.USER_EDITED, @@ -69,32 +65,3 @@ data class ApnData( var mvnoTypeEnabled = true var mvnoValueEnabled = false } - -/** - * Initialize the selected Network type Selected Options according to network type. - * @param networkType Initialized network type bitmask, often multiple network type options may be included. - * @param context The context to get network type values. - * - * @return An error message if the apn data is invalid, otherwise return null. - */ -fun getNetworkTypeSelectedOptionsState( - networkType: Int, - context: Context -): SnapshotStateList { - val networkTypeValues = context.resources.getStringArray(R.array.network_type_values) - val networkTypeSelectedOptionsState = mutableStateListOf() - if (networkType != 0) { - var i = 1 - var networkTypeBitMask = networkType - while (networkTypeBitMask != 0) { - if (networkTypeBitMask and 1 == 1 && !networkTypeSelectedOptionsState.contains(i)) { - networkTypeSelectedOptionsState.add(networkTypeValues.indexOf("$i") - 1) - } - networkTypeBitMask = networkTypeBitMask shr 1 - i++ - } - } - return networkTypeSelectedOptionsState -} - - 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 f6b23429f73..8902c73dddd 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 @@ -58,7 +58,6 @@ class ApnEditPageProviderTest { private val apnProtocolOptions = context.resources.getStringArray(R.array.apn_protocol_entries).toList() private val networkType = context.resources.getString(R.string.network_type) - private val networkTypeOptions = context.resources.getStringArray(R.array.network_type_entries).toList() private val passwordTitle = context.resources.getString(R.string.apn_password) private val apnData = mutableStateOf( ApnData( @@ -74,7 +73,7 @@ class ApnEditPageProviderTest { @Test fun apnEditPageProvider_name() { - Truth.assertThat(ApnEditPageProvider.name).isEqualTo("Apn") + Truth.assertThat(ApnEditPageProvider.name).isEqualTo("ApnEdit") } @Test @@ -218,9 +217,10 @@ class ApnEditPageProviderTest { composeTestRule.onRoot().onChild().onChildAt(0) .performScrollToNode(hasText(networkType, true)) composeTestRule.onNodeWithText(networkType, true).performClick() - composeTestRule.onNodeWithText(networkTypeOptions[1], true).performClick() - composeTestRule.onNode(hasText(networkTypeOptions[0]) and isFocused(), true).assertDoesNotExist() - composeTestRule.onNode(hasText(networkTypeOptions[1]) and isFocused(), true).assertIsDisplayed() + composeTestRule.onNodeWithText(NETWORK_TYPE_LTE, true).performClick() + composeTestRule.onNode(hasText(NETWORK_TYPE_UNSPECIFIED) and isFocused(), true) + .assertDoesNotExist() + composeTestRule.onNode(hasText(NETWORK_TYPE_LTE) and isFocused(), true).assertIsDisplayed() } @Test @@ -235,12 +235,14 @@ class ApnEditPageProviderTest { composeTestRule.onRoot().onChild().onChildAt(0) .performScrollToNode(hasText(networkType, true)) composeTestRule.onNodeWithText(networkType, true).performClick() - composeTestRule.onNodeWithText(networkTypeOptions[1], true).performClick() - composeTestRule.onNode(hasText(networkTypeOptions[0]) and isFocused(), true).assertDoesNotExist() - composeTestRule.onNode(hasText(networkTypeOptions[1]) and isFocused(), true).assertIsDisplayed() - composeTestRule.onAllNodesWithText(networkTypeOptions[1], true).onLast().performClick() - composeTestRule.onNode(hasText(networkTypeOptions[0]) and isFocused(), true).assertIsDisplayed() - composeTestRule.onNode(hasText(networkTypeOptions[1]) and isFocused(), true).assertDoesNotExist() + composeTestRule.onNodeWithText(NETWORK_TYPE_LTE, true).performClick() + composeTestRule.onNode(hasText(NETWORK_TYPE_UNSPECIFIED) and isFocused(), true) + .assertDoesNotExist() + composeTestRule.onNode(hasText(NETWORK_TYPE_LTE) and isFocused(), true).assertIsDisplayed() + composeTestRule.onAllNodesWithText(NETWORK_TYPE_LTE, true).onLast().performClick() + composeTestRule.onNode(hasText(NETWORK_TYPE_UNSPECIFIED) and isFocused(), true) + .assertIsDisplayed() + composeTestRule.onNode(hasText(NETWORK_TYPE_LTE) and isFocused(), true).assertDoesNotExist() } @Test @@ -254,4 +256,9 @@ class ApnEditPageProviderTest { .performScrollToNode(hasText(passwordTitle, true)) composeTestRule.onNodeWithText(passwordTitle, true).assertIsDisplayed() } -} \ No newline at end of file + + private companion object { + const val NETWORK_TYPE_UNSPECIFIED = "Unspecified" + const val NETWORK_TYPE_LTE = "LTE" + } +}