Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2faad6df authored by Chaohui Wang's avatar Chaohui Wang
Browse files

Check APN type is selected before save

Not allow save APN without type.

Fix: 340969975
Test: manual - APN Settings
Test: unit test
Change-Id: I91f8e8137fc234c9c860fd446b7a1e2acfa11fc7
parent 574d6419
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -3408,6 +3408,8 @@
    <string name="error_name_empty">The Name field can\u2019t be empty.</string>
    <!-- APN error dialog messages: -->
    <string name="error_apn_empty">The APN can\u2019t be empty.</string>
    <!-- APN error message about APN type cannot be empty -->
    <string name="error_apn_type_empty">The APN type can\u2019t be empty.</string>
    <!-- APN error dialog messages: -->
    <string name="error_mcc_not3">MCC field must be 3 digits.</string>
    <!-- APN error dialog messages: -->
+6 −13
Original line number Diff line number Diff line
@@ -174,20 +174,13 @@ fun validateAndSaveApnData(
 * @return An error message if the apn data is invalid, otherwise return null.
 */
fun validateApnData(apnData: ApnData, context: Context): String? {
    var errorMsg: String?
    val name = apnData.name
    val apn = apnData.apn
    errorMsg = if (name == "") {
        context.resources.getString(R.string.error_name_empty)
    } else if (apn == "") {
        context.resources.getString(R.string.error_apn_empty)
    } else {
        validateMMSC(true, apnData.mmsc, context)
    val errorMsg: String? = when {
        apnData.name.isEmpty() -> context.resources.getString(R.string.error_name_empty)
        apnData.apn.isEmpty() -> context.resources.getString(R.string.error_apn_empty)
        apnData.apnType.isEmpty() -> context.resources.getString(R.string.error_apn_type_empty)
        else -> validateMMSC(true, apnData.mmsc, context) ?: isItemExist(apnData, context)
    }
    if (errorMsg == null) {
        errorMsg = isItemExist(apnData, context)
    }
    return errorMsg?.apply { Log.d(TAG, "APN data not valid, reason: $this") }
    return errorMsg?.also { Log.d(TAG, "APN data not valid, reason: $it") }
}

/**
+3 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import com.android.settings.R
import com.android.settings.network.apn.ApnTypes.isValid
import com.android.settings.network.apn.ApnTypes.toApnType
import com.android.settingslib.spa.widget.editor.SettingsDropdownCheckBox

@@ -47,6 +48,8 @@ fun ApnTypeCheckBox(
        label = stringResource(R.string.apn_type),
        options = apnTypeOptions,
        enabled = apnData.isFieldEnabled(Telephony.Carriers.TYPE),
        errorMessage = stringResource(R.string.error_apn_type_empty)
            .takeUnless { apnTypeOptions.isValid() },
    ) {
        onTypeChanged(apnTypeOptions.toApnType())
        updateMmsSelected()
+2 −0
Original line number Diff line number Diff line
@@ -101,6 +101,8 @@ object ApnTypes {
        }
    }

    fun List<SettingsDropdownCheckOption>.isValid(): Boolean = any { it.selected.value }

    fun List<SettingsDropdownCheckOption>.toApnType(): String {
        val (selectAllOptions, regularOptions) = partition { it.isSelectAll }
        for (selectAllOption in selectAllOptions) {
+52 −0
Original line number Diff line number Diff line
@@ -17,7 +17,11 @@
package com.android.settings.network.apn

import android.telephony.data.ApnSetting
import androidx.compose.runtime.mutableStateOf
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.android.settings.network.apn.ApnTypes.isValid
import com.android.settings.network.apn.ApnTypes.toApnType
import com.android.settingslib.spa.widget.editor.SettingsDropdownCheckOption
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
@@ -25,6 +29,50 @@ import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
class ApnTypesTest {

    @Test
    fun isValid_hasSelected() {
        val options = listOf(
            SettingsDropdownCheckOption(text = APN_TYPE, selected = mutableStateOf(true)),
        )

        val isValid = options.isValid()

        assertThat(isValid).isTrue()
    }

    @Test
    fun isValid_hasNotSelected() {
        val options = listOf(
            SettingsDropdownCheckOption(text = APN_TYPE, selected = mutableStateOf(false)),
        )

        val isValid = options.isValid()

        assertThat(isValid).isFalse()
    }

    @Test
    fun toApnType_hasSelected() {
        val options = listOf(
            SettingsDropdownCheckOption(text = APN_TYPE, selected = mutableStateOf(true)),
        )

        val apnType = options.toApnType()

        assertThat(apnType).isEqualTo(APN_TYPE)
    }

    @Test
    fun toApnType_hasNotSelected() {
        val options = listOf(
            SettingsDropdownCheckOption(text = APN_TYPE, selected = mutableStateOf(false)),
        )

        val apnType = options.toApnType()

        assertThat(apnType).isEmpty()
    }

    @Test
    fun getPreSelectedApnType_regular() {
        val apnType = ApnTypes.getPreSelectedApnType(CustomizedConfig())
@@ -42,4 +90,8 @@ class ApnTypesTest {

        assertThat(apnType).isEqualTo("default,mms,supl,hipri,fota,cbs,xcap")
    }

    private companion object {
        const val APN_TYPE = "type"
    }
}