diff --git a/src/com/android/settings/network/apn/ApnEditPageProvider.kt b/src/com/android/settings/network/apn/ApnEditPageProvider.kt index 0b0431d6f2a..46849f8b98b 100644 --- a/src/com/android/settings/network/apn/ApnEditPageProvider.kt +++ b/src/com/android/settings/network/apn/ApnEditPageProvider.kt @@ -74,7 +74,7 @@ object ApnEditPageProvider : SettingsPageProvider { val apnDataCur = remember { mutableStateOf(apnDataInit) } - ApnPage(apnDataInit, apnDataCur) + ApnPage(apnDataInit, apnDataCur, uriInit) } fun getRoute( @@ -87,7 +87,7 @@ object ApnEditPageProvider : SettingsPageProvider { } @Composable -fun ApnPage(apnDataInit: ApnData, apnDataCur: MutableState) { +fun ApnPage(apnDataInit: ApnData, apnDataCur: MutableState, uriInit: Uri) { var apnData by apnDataCur val context = LocalContext.current val authTypeOptions = stringArrayResource(R.array.apn_auth_entries).toList() @@ -99,7 +99,7 @@ fun ApnPage(apnDataInit: ApnData, apnDataCur: MutableState) { title = stringResource(id = R.string.apn_edit), actions = { IconButton(onClick = { - validateAndSaveApnData(apnDataInit, apnData, context) + validateAndSaveApnData(apnDataInit, apnData, context, uriInit) }) { Icon(imageVector = Icons.Outlined.Done, contentDescription = "Save APN") } } ) { diff --git a/src/com/android/settings/network/apn/ApnRepository.kt b/src/com/android/settings/network/apn/ApnRepository.kt index a518aa5e38b..e0121b4926a 100644 --- a/src/com/android/settings/network/apn/ApnRepository.kt +++ b/src/com/android/settings/network/apn/ApnRepository.kt @@ -16,11 +16,13 @@ package com.android.settings.network.apn +import android.content.ContentValues import android.content.Context import android.net.Uri import android.provider.Telephony import android.util.Log import com.android.settings.R +import com.android.settingslib.utils.ThreadUtils import java.util.Locale const val NAME_INDEX = 1 @@ -161,4 +163,35 @@ private fun convertProtocol2Options(raw: String, context: Context): String { "" } } +} + +fun convertOptions2Protocol(protocolIndex: Int, context: Context): String { + val apnProtocolValues = context.resources.getStringArray(R.array.apn_protocol_values).toList() + + return if (protocolIndex == -1) { + "" + } else { + try { + apnProtocolValues[protocolIndex] + } catch (e: ArrayIndexOutOfBoundsException) { + "" + } + } +} + +fun updateApnDataToDatabase(newApn: Boolean, values: ContentValues, context: Context, uriInit: Uri) { + ThreadUtils.postOnBackgroundThread { + if (newApn) { + // Add a new apn to the database + val newUri = context.contentResolver.insert(uriInit, values) + if (newUri == null) { + Log.e(TAG, "Can't add a new apn to database $uriInit") + } + } else { + // Update the existing apn + context.contentResolver.update( + uriInit, values, null /* where */, null /* selection Args */ + ) + } + } } \ No newline at end of file diff --git a/src/com/android/settings/network/apn/ApnStatus.kt b/src/com/android/settings/network/apn/ApnStatus.kt index 5904e98d8bf..a5a215bd30b 100644 --- a/src/com/android/settings/network/apn/ApnStatus.kt +++ b/src/com/android/settings/network/apn/ApnStatus.kt @@ -16,6 +16,7 @@ package com.android.settings.network.apn +import android.content.ContentValues import android.content.Context import android.net.Uri import android.os.Bundle @@ -68,7 +69,29 @@ data class ApnData( val newApn: Boolean = false, val subId: Int = -1, val customizedConfig: CustomizedConfig = CustomizedConfig() -) +) { + fun getContentValues(context: Context): ContentValues { + val values = ContentValues() + values.put(Telephony.Carriers.NAME, name) + values.put(Telephony.Carriers.APN, apn) + values.put(Telephony.Carriers.PROXY, proxy) + values.put(Telephony.Carriers.PORT, port) + values.put(Telephony.Carriers.MMSPROXY, mmsProxy) + values.put(Telephony.Carriers.MMSPORT, mmsPort) + values.put(Telephony.Carriers.USER, userName) + values.put(Telephony.Carriers.SERVER, server) + values.put(Telephony.Carriers.PASSWORD, passWord) + values.put(Telephony.Carriers.MMSC, mmsc) + values.put(Telephony.Carriers.AUTH_TYPE, authType) + values.put(Telephony.Carriers.PROTOCOL, convertOptions2Protocol(apnProtocol, context)) + values.put(Telephony.Carriers.ROAMING_PROTOCOL, convertOptions2Protocol(apnRoaming, context)) + values.put(Telephony.Carriers.TYPE, apnType) + values.put(Telephony.Carriers.NETWORK_TYPE_BITMASK, networkType) + values.put(Telephony.Carriers.CARRIER_ENABLED, apnEnable) + values.put(Telephony.Carriers.EDITED_STATUS, Telephony.Carriers.USER_EDITED) + return values + } +} data class CustomizedConfig( val newApn: Boolean = false, @@ -181,7 +204,7 @@ fun getApnDataInit(arguments: Bundle, context: Context, uriInit: Uri, subId: Int * * @return true if there is no error */ -fun validateAndSaveApnData(apnDataInit: ApnData, apnData: ApnData, context: Context): Boolean { +fun validateAndSaveApnData(apnDataInit: ApnData, apnData: ApnData, context: Context, uriInit: Uri): Boolean { // Nothing to do if it's a read only APN if (apnData.customizedConfig.readOnlyApn) { return true @@ -193,7 +216,7 @@ fun validateAndSaveApnData(apnDataInit: ApnData, apnData: ApnData, context: Cont } if (apnData.newApn || (apnData != apnDataInit)) { Log.d(TAG, "validateAndSaveApnData: apnData ${apnData.name}") - // TODO: updateApnDataToDatabase + updateApnDataToDatabase(apnData.newApn, apnData.getContentValues(context), context, uriInit) } return true } 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 ddc836473e2..20d67fc2a22 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,6 +17,7 @@ package com.android.settings.network.apn import android.content.Context +import android.net.Uri import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.ui.test.assertIsDisplayed @@ -40,6 +41,7 @@ import com.google.common.truth.Truth import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith +import org.mockito.kotlin.mock @RunWith(AndroidJUnit4::class) class ApnEditPageProviderTest { @@ -68,6 +70,7 @@ class ApnEditPageProviderTest { private val apnData = mutableStateOf( apnInit ) + private val uri = mock {} @Test fun apnEditPageProvider_name() { @@ -77,9 +80,7 @@ class ApnEditPageProviderTest { @Test fun title_displayed() { composeTestRule.setContent { - ApnPage(apnInit, remember { - apnData - }) + ApnPage(apnInit, remember { apnData }, uri) } composeTestRule.onNodeWithText(context.getString(R.string.apn_edit)).assertIsDisplayed() } @@ -87,9 +88,7 @@ class ApnEditPageProviderTest { @Test fun name_displayed() { composeTestRule.setContent { - ApnPage(apnInit, remember { - apnData - }) + ApnPage(apnInit, remember { apnData }, uri) } composeTestRule.onNodeWithText(apnName, true).assertIsDisplayed() } @@ -97,9 +96,7 @@ class ApnEditPageProviderTest { @Test fun mmsc_displayed() { composeTestRule.setContent { - ApnPage(apnInit, remember { - apnData - }) + ApnPage(apnInit, remember { apnData }, uri) } composeTestRule.onRoot().onChild().onChildAt(0) .performScrollToNode(hasText(mmsc, true)) @@ -109,9 +106,7 @@ class ApnEditPageProviderTest { @Test fun mms_proxy_displayed() { composeTestRule.setContent { - ApnPage(apnInit, remember { - apnData - }) + ApnPage(apnInit, remember { apnData }, uri) } composeTestRule.onRoot().onChild().onChildAt(0) .performScrollToNode(hasText(mmsProxy, true)) @@ -121,9 +116,7 @@ class ApnEditPageProviderTest { @Test fun apn_type_displayed() { composeTestRule.setContent { - ApnPage(apnInit, remember { - apnData - }) + ApnPage(apnInit, remember { apnData }, uri) } composeTestRule.onRoot().onChild().onChildAt(0) .performScrollToNode(hasText(apnType, true)) @@ -133,9 +126,7 @@ class ApnEditPageProviderTest { @Test fun apn_roaming_displayed() { composeTestRule.setContent { - ApnPage(apnInit, remember { - apnData - }) + ApnPage(apnInit, remember { apnData }, uri) } composeTestRule.onRoot().onChild().onChildAt(0) .performScrollToNode(hasText(apnRoaming, true)) @@ -145,9 +136,7 @@ class ApnEditPageProviderTest { @Test fun carrier_enabled_displayed() { composeTestRule.setContent { - ApnPage(apnInit, remember { - apnData - }) + ApnPage(apnInit, remember { apnData }, uri) } composeTestRule.onRoot().onChild().onChildAt(0) .performScrollToNode(hasText(apnEnable, true)) @@ -157,9 +146,7 @@ class ApnEditPageProviderTest { @Test fun carrier_enabled_isChecked() { composeTestRule.setContent { - ApnPage(apnInit, remember { - apnData - }) + ApnPage(apnInit, remember { apnData }, uri) } composeTestRule.onRoot().onChild().onChildAt(0) .performScrollToNode(hasText(apnEnable, true)) @@ -169,9 +156,7 @@ class ApnEditPageProviderTest { @Test fun carrier_enabled_checkChanged() { composeTestRule.setContent { - ApnPage(apnInit, remember { - apnData - }) + ApnPage(apnInit, remember { apnData }, uri) } composeTestRule.onRoot().onChild().onChildAt(0) .performScrollToNode(hasText(apnEnable, true)) @@ -182,9 +167,7 @@ class ApnEditPageProviderTest { @Test fun network_type_displayed() { composeTestRule.setContent { - ApnPage(apnInit, remember { - apnData - }) + ApnPage(apnInit, remember { apnData }, uri) } composeTestRule.onRoot().onChild().onChildAt(0) .performScrollToNode(hasText(networkType, true)) @@ -194,9 +177,7 @@ class ApnEditPageProviderTest { @Test fun network_type_changed() { composeTestRule.setContent { - ApnPage(apnInit, remember { - apnData - }) + ApnPage(apnInit, remember { apnData }, uri) } composeTestRule.onRoot().onChild().onChildAt(0) .performScrollToNode(hasText(networkType, true)) @@ -210,9 +191,7 @@ class ApnEditPageProviderTest { @Test fun network_type_changed_back2Default() { composeTestRule.setContent { - ApnPage(apnInit, remember { - apnData - }) + ApnPage(apnInit, remember { apnData }, uri) } composeTestRule.onRoot().onChild().onChildAt(0) .performScrollToNode(hasText(networkType, true)) @@ -230,9 +209,7 @@ class ApnEditPageProviderTest { @Test fun password_displayed() { composeTestRule.setContent { - ApnPage(apnInit, remember { - apnData - }) + ApnPage(apnInit, remember { apnData }, uri) } composeTestRule.onRoot().onChild().onChildAt(0) .performScrollToNode(hasText(passwordTitle, true))