Merge "[Spa] Fix State<T> as a parameter of SwitchPreference" into main

This commit is contained in:
Chaohui Wang
2023-11-06 04:19:30 +00:00
committed by Android (Google) Code Review
9 changed files with 37 additions and 39 deletions

View File

@@ -38,7 +38,6 @@ 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
import com.android.settingslib.spa.widget.editor.SettingsExposedDropdownMenuCheckBox
import com.android.settingslib.spa.widget.editor.SettingsOutlinedTextField
@@ -186,10 +185,8 @@ fun ApnPage(apnDataInit: ApnData, apnDataCur: MutableState<ApnData>, uriInit: Ur
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)
}

View File

@@ -28,7 +28,7 @@ import android.permission.PermissionControllerManager.HIBERNATION_ELIGIBILITY_UN
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 @@ fun HibernationSwitchPreference(app: ApplicationInfo) {
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
}
})

View File

@@ -24,10 +24,9 @@ import android.content.Context
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 @@ class AlarmsAndRemindersAppListModel(
}
@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

View File

@@ -24,8 +24,8 @@ import android.content.Context
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 @@ class InstallUnknownAppsListModel(private val context: Context) :
@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))

View File

@@ -23,8 +23,8 @@ import android.content.pm.PackageManager.PackageInfoFlags
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 @@ class NfcTagAppsSettingsListModel(private val context: Context) :
@Composable
override fun isAllowed(record: NfcTagAppsSettingsRecord) =
record.controller.isAllowed.observeAsState()
record.controller.isAllowed.observeAsCallback()
override fun isChangeable(record: NfcTagAppsSettingsRecord) = true

View File

@@ -25,8 +25,8 @@ import android.content.pm.PackageManager.GET_ACTIVITIES
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 @@ class PictureInPictureListModel(private val context: Context) :
@Composable
override fun isAllowed(record: PictureInPictureRecord) =
record.appOpsController.isAllowed.observeAsState()
record.appOpsController.isAllowed.observeAsCallback()
override fun isChangeable(record: PictureInPictureRecord) = record.isSupport

View File

@@ -20,8 +20,9 @@ import android.content.pm.PackageManager
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 @@ fun AirplaneModePreference() {
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)
}

View File

@@ -21,7 +21,7 @@ import android.content.Context
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.notification.app.AppNotificationSettings
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.model.app.AppRecord
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 @@ class AppNotificationsListModel(
@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,
)
}

View File

@@ -18,11 +18,8 @@ package com.android.settings.spa.app.specialaccess
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.Rule
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 @@ class WifiControlAppListModelTest {
}
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 {