Merge "Fix IMEI is not selectable" into main
diff --git a/src/com/android/settings/network/apn/ApnEditPageProvider.kt b/src/com/android/settings/network/apn/ApnEditPageProvider.kt
index 81da0bf..0ed54e7 100644
--- a/src/com/android/settings/network/apn/ApnEditPageProvider.kt
+++ b/src/com/android/settings/network/apn/ApnEditPageProvider.kt
@@ -38,7 +38,6 @@
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
import com.android.settingslib.spa.widget.editor.SettingsExposedDropdownMenuCheckBox
import com.android.settingslib.spa.widget.editor.SettingsOutlinedTextField
@@ -186,10 +185,8 @@
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 changeable = { apnData.apnEnableEnabled }
+ override val checked = { apnData.apnEnable }
override val onCheckedChange = { newChecked: Boolean ->
apnData = apnData.copy(apnEnable = newChecked)
}
diff --git a/src/com/android/settings/spa/app/appinfo/HibernationSwitchPreference.kt b/src/com/android/settings/spa/app/appinfo/HibernationSwitchPreference.kt
index 77d68b5..78ca15b 100644
--- a/src/com/android/settings/spa/app/appinfo/HibernationSwitchPreference.kt
+++ b/src/com/android/settings/spa/app/appinfo/HibernationSwitchPreference.kt
@@ -28,7 +28,7 @@
import android.provider.DeviceConfig
import android.provider.DeviceConfig.NAMESPACE_APP_HIBERNATION
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.derivedStateOf
+import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalContext
import androidx.lifecycle.compose.collectAsStateWithLifecycle
@@ -56,18 +56,14 @@
val presenter = remember { HibernationSwitchPresenter(context, app) }
if (!presenter.isAvailable()) return
- val isEligibleState = presenter.isEligibleFlow.collectAsStateWithLifecycle(initialValue = false)
+ val isEligibleState by presenter.isEligibleFlow.collectAsStateWithLifecycle(initialValue = false)
val isCheckedState = presenter.isCheckedFlow.collectAsStateWithLifecycle(initialValue = null)
SwitchPreference(remember {
object : SwitchPreferenceModel {
override val title = context.getString(R.string.unused_apps_switch)
override val summary = { context.getString(R.string.unused_apps_switch_summary) }
- override val changeable = isEligibleState
-
- override val checked = derivedStateOf {
- if (!changeable.value) false else isCheckedState.value
- }
-
+ override val changeable = { isEligibleState }
+ override val checked = { if (changeable()) isCheckedState.value else false }
override val onCheckedChange = presenter::onCheckedChange
}
})
diff --git a/src/com/android/settings/spa/app/specialaccess/AlarmsAndRemindersAppList.kt b/src/com/android/settings/spa/app/specialaccess/AlarmsAndRemindersAppList.kt
index c31eb7a..c990927 100644
--- a/src/com/android/settings/spa/app/specialaccess/AlarmsAndRemindersAppList.kt
+++ b/src/com/android/settings/spa/app/specialaccess/AlarmsAndRemindersAppList.kt
@@ -24,10 +24,9 @@
import android.content.pm.ApplicationInfo
import android.os.PowerExemptionManager
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.livedata.observeAsState
import com.android.settings.overlay.FeatureFactory.Companion.featureFactory
import com.android.settingslib.R
-import com.android.settingslib.spa.framework.compose.stateOf
+import com.android.settingslib.spa.livedata.observeAsCallback
import com.android.settingslib.spaprivileged.model.app.AppRecord
import com.android.settingslib.spaprivileged.model.app.IPackageManagers
import com.android.settingslib.spaprivileged.model.app.PackageManagers
@@ -79,9 +78,10 @@
}
@Composable
- override fun isAllowed(record: AlarmsAndRemindersAppRecord) =
- if (record.isTrumped) stateOf(true)
- else record.controller.isAllowed.observeAsState()
+ override fun isAllowed(record: AlarmsAndRemindersAppRecord): () -> Boolean? = when {
+ record.isTrumped -> ({ true })
+ else -> record.controller.isAllowed.observeAsCallback()
+ }
override fun isChangeable(record: AlarmsAndRemindersAppRecord) = record.isChangeable
diff --git a/src/com/android/settings/spa/app/specialaccess/InstallUnknownApps.kt b/src/com/android/settings/spa/app/specialaccess/InstallUnknownApps.kt
index c98b2ee..7f63e38 100644
--- a/src/com/android/settings/spa/app/specialaccess/InstallUnknownApps.kt
+++ b/src/com/android/settings/spa/app/specialaccess/InstallUnknownApps.kt
@@ -24,8 +24,8 @@
import android.content.pm.ApplicationInfo
import android.os.UserManager
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.livedata.observeAsState
import com.android.settings.R
+import com.android.settingslib.spa.livedata.observeAsCallback
import com.android.settingslib.spaprivileged.model.app.AppOpsController
import com.android.settingslib.spaprivileged.model.app.AppRecord
import com.android.settingslib.spaprivileged.model.app.userId
@@ -79,7 +79,7 @@
@Composable
override fun isAllowed(record: InstallUnknownAppsRecord) =
- record.appOpsController.isAllowed.observeAsState()
+ record.appOpsController.isAllowed.observeAsCallback()
override fun isChangeable(record: InstallUnknownAppsRecord) =
isChangeable(record, getPotentialPackageNames(record.app.userId))
diff --git a/src/com/android/settings/spa/app/specialaccess/NfcTagAppsSettings.kt b/src/com/android/settings/spa/app/specialaccess/NfcTagAppsSettings.kt
index 3dede42..f02a6a1 100644
--- a/src/com/android/settings/spa/app/specialaccess/NfcTagAppsSettings.kt
+++ b/src/com/android/settings/spa/app/specialaccess/NfcTagAppsSettings.kt
@@ -23,8 +23,8 @@
import android.nfc.NfcAdapter
import android.util.Log
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.livedata.observeAsState
import com.android.settings.R
+import com.android.settingslib.spa.livedata.observeAsCallback
import com.android.settingslib.spaprivileged.model.app.AppRecord
import com.android.settingslib.spaprivileged.model.app.userId
import com.android.settingslib.spaprivileged.template.app.TogglePermissionAppListModel
@@ -100,7 +100,7 @@
@Composable
override fun isAllowed(record: NfcTagAppsSettingsRecord) =
- record.controller.isAllowed.observeAsState()
+ record.controller.isAllowed.observeAsCallback()
override fun isChangeable(record: NfcTagAppsSettingsRecord) = true
diff --git a/src/com/android/settings/spa/app/specialaccess/PictureInPicture.kt b/src/com/android/settings/spa/app/specialaccess/PictureInPicture.kt
index 5ed3615..cd615919 100644
--- a/src/com/android/settings/spa/app/specialaccess/PictureInPicture.kt
+++ b/src/com/android/settings/spa/app/specialaccess/PictureInPicture.kt
@@ -25,8 +25,8 @@
import android.content.pm.PackageManager.PackageInfoFlags
import android.util.Log
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.livedata.observeAsState
import com.android.settings.R
+import com.android.settingslib.spa.livedata.observeAsCallback
import com.android.settingslib.spaprivileged.model.app.AppOpsController
import com.android.settingslib.spaprivileged.model.app.AppRecord
import com.android.settingslib.spaprivileged.model.app.installed
@@ -90,7 +90,7 @@
@Composable
override fun isAllowed(record: PictureInPictureRecord) =
- record.appOpsController.isAllowed.observeAsState()
+ record.appOpsController.isAllowed.observeAsCallback()
override fun isChangeable(record: PictureInPictureRecord) = record.isSupport
diff --git a/src/com/android/settings/spa/network/AirplaneModePreference.kt b/src/com/android/settings/spa/network/AirplaneModePreference.kt
index 462c121..27261b6 100644
--- a/src/com/android/settings/spa/network/AirplaneModePreference.kt
+++ b/src/com/android/settings/spa/network/AirplaneModePreference.kt
@@ -20,8 +20,9 @@
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.AirplanemodeActive
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.remember
+import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
+import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalContext
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
@@ -37,11 +38,12 @@
val context = LocalContext.current
val controller = remember { AirplaneModeController(context) }
if (!controller.isAvailable()) return
+ val checked by controller.airplaneModeState.observeAsState(
+ initial = controller.isAirplaneModeOn()
+ )
SwitchPreference(object : SwitchPreferenceModel {
override val title = context.getString(R.string.airplane_mode)
- override val checked = controller.airplaneModeState.observeAsState(
- initial = controller.isAirplaneModeOn()
- )
+ override val checked = { checked }
override val onCheckedChange = { newChecked: Boolean ->
controller.setChecked(newChecked)
}
diff --git a/src/com/android/settings/spa/notification/AppNotificationsListModel.kt b/src/com/android/settings/spa/notification/AppNotificationsListModel.kt
index 692ffcb..2f3de3a 100644
--- a/src/com/android/settings/spa/notification/AppNotificationsListModel.kt
+++ b/src/com/android/settings/spa/notification/AppNotificationsListModel.kt
@@ -21,7 +21,7 @@
import android.content.pm.ApplicationInfo
import android.icu.text.RelativeDateTimeFormatter
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.livedata.observeAsState
+import androidx.compose.runtime.getValue
import androidx.compose.runtime.produceState
import com.android.settings.R
import com.android.settings.applications.AppInfoBase
@@ -29,6 +29,7 @@
import com.android.settings.spa.notification.SpinnerItem.Companion.toSpinnerItem
import com.android.settingslib.spa.framework.util.asyncFilter
import com.android.settingslib.spa.framework.util.asyncForEach
+import com.android.settingslib.spa.livedata.observeAsCallback
import com.android.settingslib.spa.widget.ui.SpinnerOption
import com.android.settingslib.spaprivileged.model.app.AppEntry
import com.android.settingslib.spaprivileged.model.app.AppListModel
@@ -36,9 +37,11 @@
import com.android.settingslib.spaprivileged.template.app.AppListItemModel
import com.android.settingslib.spaprivileged.template.app.AppListTwoTargetSwitchItem
import com.android.settingslib.utils.StringUtil
+import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.withContext
data class AppNotificationsRecord(
override val app: ApplicationInfo,
@@ -117,12 +120,15 @@
@Composable
override fun AppListItemModel<AppNotificationsRecord>.AppItem() {
+ val changeable by produceState(initialValue = false) {
+ withContext(Dispatchers.Default) {
+ value = repository.isChangeable(record.app)
+ }
+ }
AppListTwoTargetSwitchItem(
onClick = { navigateToAppNotificationSettings(app = record.app) },
- checked = record.controller.isEnabled.observeAsState(),
- changeable = produceState(initialValue = false) {
- value = repository.isChangeable(record.app)
- },
+ checked = record.controller.isEnabled.observeAsCallback(),
+ changeable = { changeable },
onCheckedChange = record.controller::setEnabled,
)
}
diff --git a/tests/spa_unit/src/com/android/settings/spa/app/WifiControlAppListModelTest.kt b/tests/spa_unit/src/com/android/settings/spa/app/WifiControlAppListModelTest.kt
index c5c48f5..74aa861 100644
--- a/tests/spa_unit/src/com/android/settings/spa/app/WifiControlAppListModelTest.kt
+++ b/tests/spa_unit/src/com/android/settings/spa/app/WifiControlAppListModelTest.kt
@@ -18,11 +18,8 @@
import android.Manifest
import android.app.AppOpsManager
-import android.app.AppOpsManager.MODE_ALLOWED
-import android.app.AppOpsManager.MODE_DEFAULT
import android.content.Context
import android.content.pm.ApplicationInfo
-import androidx.compose.runtime.State
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.lifecycle.MutableLiveData
import androidx.test.core.app.ApplicationProvider
@@ -40,9 +37,9 @@
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
-import org.mockito.Mockito.`when` as whenever
import org.mockito.junit.MockitoJUnit
import org.mockito.junit.MockitoRule
+import org.mockito.Mockito.`when` as whenever
@ExperimentalCoroutinesApi
@RunWith(AndroidJUnit4::class)
@@ -248,9 +245,9 @@
}
private fun getIsAllowed(record: AppOpPermissionRecord): Boolean? {
- lateinit var isAllowedState: State<Boolean?>
+ lateinit var isAllowedState: () -> Boolean?
composeTestRule.setContent { isAllowedState = listModel.isAllowed(record) }
- return isAllowedState.value
+ return isAllowedState()
}
private companion object {
diff --git a/tests/spa_unit/src/com/android/settings/spa/app/specialaccess/AllFilesAccessTest.kt b/tests/spa_unit/src/com/android/settings/spa/app/specialaccess/AllFilesAccessTest.kt
index f5d422d..4c65d90 100644
--- a/tests/spa_unit/src/com/android/settings/spa/app/specialaccess/AllFilesAccessTest.kt
+++ b/tests/spa_unit/src/com/android/settings/spa/app/specialaccess/AllFilesAccessTest.kt
@@ -33,33 +33,12 @@
private val listModel = AllFilesAccessListModel(context)
@Test
- fun pageTitleResId() {
+ fun modelResourceIdAndProperties() {
assertThat(listModel.pageTitleResId).isEqualTo(R.string.manage_external_storage_title)
- }
-
- @Test
- fun switchTitleResId() {
assertThat(listModel.switchTitleResId).isEqualTo(R.string.permit_manage_external_storage)
- }
-
- @Test
- fun footerResId() {
- assertThat(listModel.footerResId)
- .isEqualTo(R.string.allow_manage_external_storage_description)
- }
-
- @Test
- fun appOp() {
+ assertThat(listModel.footerResId).isEqualTo(R.string.allow_manage_external_storage_description)
assertThat(listModel.appOp).isEqualTo(AppOpsManager.OP_MANAGE_EXTERNAL_STORAGE)
- }
-
- @Test
- fun permission() {
assertThat(listModel.permission).isEqualTo(Manifest.permission.MANAGE_EXTERNAL_STORAGE)
- }
-
- @Test
- fun setModeByUid() {
assertThat(listModel.setModeByUid).isTrue()
}
}
\ No newline at end of file
diff --git a/tests/spa_unit/src/com/android/settings/spa/app/specialaccess/MediaManagementAppsTest.kt b/tests/spa_unit/src/com/android/settings/spa/app/specialaccess/MediaManagementAppsTest.kt
index b56d997..b901043 100644
--- a/tests/spa_unit/src/com/android/settings/spa/app/specialaccess/MediaManagementAppsTest.kt
+++ b/tests/spa_unit/src/com/android/settings/spa/app/specialaccess/MediaManagementAppsTest.kt
@@ -33,33 +33,12 @@
private val listModel = MediaManagementAppsListModel(context)
@Test
- fun pageTitleResId() {
+ fun modelResourceIdAndProperties() {
assertThat(listModel.pageTitleResId).isEqualTo(R.string.media_management_apps_title)
- }
-
- @Test
- fun switchTitleResId() {
- assertThat(listModel.switchTitleResId)
- .isEqualTo(R.string.media_management_apps_toggle_label)
- }
-
- @Test
- fun footerResId() {
+ assertThat(listModel.switchTitleResId).isEqualTo(R.string.media_management_apps_toggle_label)
assertThat(listModel.footerResId).isEqualTo(R.string.media_management_apps_description)
- }
-
- @Test
- fun appOp() {
assertThat(listModel.appOp).isEqualTo(AppOpsManager.OP_MANAGE_MEDIA)
- }
-
- @Test
- fun permission() {
assertThat(listModel.permission).isEqualTo(Manifest.permission.MANAGE_MEDIA)
- }
-
- @Test
- fun setModeByUid() {
assertThat(listModel.setModeByUid).isTrue()
}
}
\ No newline at end of file
diff --git a/tests/spa_unit/src/com/android/settings/spa/app/specialaccess/PictureInPictureTest.kt b/tests/spa_unit/src/com/android/settings/spa/app/specialaccess/PictureInPictureTest.kt
index 6054bb5..4229247 100644
--- a/tests/spa_unit/src/com/android/settings/spa/app/specialaccess/PictureInPictureTest.kt
+++ b/tests/spa_unit/src/com/android/settings/spa/app/specialaccess/PictureInPictureTest.kt
@@ -67,18 +67,9 @@
}
@Test
- fun pageTitleResId() {
+ fun modelResourceId() {
assertThat(listModel.pageTitleResId).isEqualTo(R.string.picture_in_picture_title)
- }
-
- @Test
- fun switchTitleResId() {
- assertThat(listModel.switchTitleResId)
- .isEqualTo(R.string.picture_in_picture_app_detail_switch)
- }
-
- @Test
- fun footerResId() {
+ assertThat(listModel.switchTitleResId).isEqualTo(R.string.picture_in_picture_app_detail_switch)
assertThat(listModel.footerResId).isEqualTo(R.string.picture_in_picture_app_detail_summary)
}
diff --git a/tests/spa_unit/src/com/android/settings/spa/app/specialaccess/TurnScreenOnAppsTest.kt b/tests/spa_unit/src/com/android/settings/spa/app/specialaccess/TurnScreenOnAppsTest.kt
index 54ae6c6..9c6079d 100644
--- a/tests/spa_unit/src/com/android/settings/spa/app/specialaccess/TurnScreenOnAppsTest.kt
+++ b/tests/spa_unit/src/com/android/settings/spa/app/specialaccess/TurnScreenOnAppsTest.kt
@@ -31,32 +31,12 @@
private val listModel = TurnScreenOnAppsListModel(context)
@Test
- fun pageTitleResId() {
+ fun modelResourceIdAndProperties() {
assertThat(listModel.pageTitleResId).isEqualTo(com.android.settingslib.R.string.turn_screen_on_title)
- }
-
- @Test
- fun switchTitleResId() {
assertThat(listModel.switchTitleResId).isEqualTo(com.android.settingslib.R.string.allow_turn_screen_on)
- }
-
- @Test
- fun footerResId() {
assertThat(listModel.footerResId).isEqualTo(com.android.settingslib.R.string.allow_turn_screen_on_description)
- }
-
- @Test
- fun appOp() {
assertThat(listModel.appOp).isEqualTo(AppOpsManager.OP_TURN_SCREEN_ON)
- }
-
- @Test
- fun permission() {
assertThat(listModel.permission).isEqualTo(Manifest.permission.TURN_SCREEN_ON)
- }
-
- @Test
- fun setModeByUid() {
assertThat(listModel.setModeByUid).isTrue()
}
}
\ No newline at end of file
diff --git a/tests/spa_unit/src/com/android/settings/spa/app/specialaccess/VoiceActivationAppsTest.kt b/tests/spa_unit/src/com/android/settings/spa/app/specialaccess/VoiceActivationAppsTest.kt
index 7d636b3..a2aa293 100644
--- a/tests/spa_unit/src/com/android/settings/spa/app/specialaccess/VoiceActivationAppsTest.kt
+++ b/tests/spa_unit/src/com/android/settings/spa/app/specialaccess/VoiceActivationAppsTest.kt
@@ -17,34 +17,14 @@
private val listModel = VoiceActivationAppsListModel(context)
@Test
- fun pageTitleResId() {
+ fun modelResourceIdAndProperties() {
assertThat(listModel.pageTitleResId).isEqualTo(R.string.voice_activation_apps_title)
- }
-
- @Test
- fun switchTitleResId() {
assertThat(listModel.switchTitleResId).isEqualTo(R.string.permit_voice_activation_apps)
- }
-
- @Test
- fun footerResId() {
- assertThat(listModel.footerResId)
- .isEqualTo(R.string.allow_voice_activation_apps_description)
- }
-
- @Test
- fun appOp() {
+ assertThat(listModel.footerResId).isEqualTo(R.string.allow_voice_activation_apps_description)
assertThat(listModel.appOp).isEqualTo(AppOpsManager.OP_RECEIVE_SANDBOX_TRIGGER_AUDIO)
- }
-
- @Test
- fun permission() {
assertThat(listModel.permission).isEqualTo(
- Manifest.permission.RECEIVE_SANDBOX_TRIGGER_AUDIO)
- }
-
- @Test
- fun setModeByUid() {
+ Manifest.permission.RECEIVE_SANDBOX_TRIGGER_AUDIO
+ )
assertThat(listModel.setModeByUid).isTrue()
}
}
\ No newline at end of file