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

Commit c63b8dbe authored by Chaohui Wang's avatar Chaohui Wang Committed by Android (Google) Code Review
Browse files

Merge "[Spa] Support override summary when restricted" into main

parents 1a99df7c 089df8d6
Loading
Loading
Loading
Loading
+11 −1
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.settingslib.spa.gallery.restricted

import android.content.Context
import android.content.Intent
import com.android.settingslib.spa.restricted.Blocked.SwitchPreferenceOverrides
import com.android.settingslib.spa.restricted.BlockedWithDetails
import com.android.settingslib.spa.restricted.NoRestricted
import com.android.settingslib.spa.restricted.RestrictedMode
@@ -25,6 +26,7 @@ import com.android.settingslib.spa.restricted.RestrictedRepository
import com.android.settingslib.spa.restricted.Restrictions
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.map

class GalleryRestrictedRepository(private val context: Context) : RestrictedRepository {
@@ -33,7 +35,13 @@ class GalleryRestrictedRepository(private val context: Context) : RestrictedRepo
        return enableRestrictionsFlow.map { enableRestrictions ->
            if (enableRestrictions && restrictions.isRestricted) {
                object : BlockedWithDetails {
                    override val canOverrideSwitchChecked = true
                    override val switchPreferenceOverridesFlow =
                        combine(summaryOnFlow, summaryOffFlow) { summaryOn, summaryOff ->
                            SwitchPreferenceOverrides(
                                summaryOn = summaryOn,
                                summaryOff = summaryOff,
                            )
                        }

                    override fun showDetails() {
                        context.startActivity(Intent("android.settings.SHOW_ADMIN_SUPPORT_DETAILS"))
@@ -47,5 +55,7 @@ class GalleryRestrictedRepository(private val context: Context) : RestrictedRepo

    companion object {
        var enableRestrictionsFlow = MutableStateFlow(true)
        var summaryOnFlow = MutableStateFlow("Force on")
        var summaryOffFlow = MutableStateFlow("Force off")
    }
}
+15 −2
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import com.android.settingslib.spa.framework.common.SettingsPageProvider
import com.android.settingslib.spa.framework.compose.navigator
import com.android.settingslib.spa.restricted.RestrictedMainSwitchPreference
import com.android.settingslib.spa.restricted.RestrictedSwitchPreference
import com.android.settingslib.spa.widget.editor.SettingsOutlinedTextField
import com.android.settingslib.spa.widget.preference.MainSwitchPreference
import com.android.settingslib.spa.widget.preference.Preference
import com.android.settingslib.spa.widget.preference.PreferenceModel
@@ -42,7 +43,7 @@ object RestrictedSwitchPreferencePageProvider : SettingsPageProvider {
    @Composable
    override fun Page(arguments: Bundle?) {
        RegularScaffold(TITLE) {
            EnableRestrictionsSwitchPreference()
            Configs()

            SampleRestrictedMainSwitchPreference(ifBlockedOverrideCheckedTo = null)
            SampleRestrictedMainSwitchPreference(ifBlockedOverrideCheckedTo = true)
@@ -68,9 +69,11 @@ object RestrictedSwitchPreferencePageProvider : SettingsPageProvider {
}

@Composable
private fun EnableRestrictionsSwitchPreference() {
private fun Configs() {
    val enableRestrictions by
        GalleryRestrictedRepository.enableRestrictionsFlow.collectAsStateWithLifecycle()
    val summaryOn by GalleryRestrictedRepository.summaryOnFlow.collectAsStateWithLifecycle()
    val summaryOff by GalleryRestrictedRepository.summaryOffFlow.collectAsStateWithLifecycle()
    MainSwitchPreference(
        model =
            object : SwitchPreferenceModel {
@@ -81,6 +84,16 @@ private fun EnableRestrictionsSwitchPreference() {
                }
            }
    )
    SettingsOutlinedTextField(
        value = summaryOn,
        label = "Override summary on",
        onTextChange = { GalleryRestrictedRepository.summaryOnFlow.value = it },
    )
    SettingsOutlinedTextField(
        value = summaryOff,
        label = "Override summary off",
        onTextChange = { GalleryRestrictedRepository.summaryOffFlow.value = it },
    )
}

@Composable
+51 −11
Original line number Diff line number Diff line
@@ -16,15 +16,24 @@

package com.android.settingslib.spa.restricted

import androidx.compose.foundation.clickable
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.semantics.toggleableState
import androidx.compose.ui.state.ToggleableState
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.android.settingslib.spa.R
import com.android.settingslib.spa.framework.common.SpaEnvironmentFactory
import com.android.settingslib.spa.widget.preference.SwitchPreferenceModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.conflate
import kotlinx.coroutines.flow.flowOn

@Composable
@@ -52,18 +61,49 @@ internal fun RestrictedBaseSwitchPreference(
    }
    val restrictedModeFlow =
        remember(restrictions) {
            repository.restrictedModeFlow(restrictions).flowOn(Dispatchers.Default)
            repository.restrictedModeFlow(restrictions).conflate().flowOn(Dispatchers.Default)
        }
    val restrictedMode by
        restrictedModeFlow.collectAsStateWithLifecycle(initialValue = NoRestricted)
    val restrictedSwitchPreferenceModel =
        remember(restrictedMode, model, ifBlockedOverrideCheckedTo) {
            RestrictedSwitchPreferenceModel(
                model = model,
                restrictedMode = restrictedMode,
                ifBlockedOverrideCheckedTo = ifBlockedOverrideCheckedTo,
    val restrictedMode by restrictedModeFlow.collectAsStateWithLifecycle(initialValue = null)
    val presenter =
        remember(model, ifBlockedOverrideCheckedTo) {
            RestrictedSwitchPreferencePresenter(model, ifBlockedOverrideCheckedTo)
        }
    val restrictedModel by
        remember(presenter, restrictedMode) { presenter.restrictedModelFlow(restrictedMode) }
            .collectAsStateWithLifecycle(initialValue = presenter.indeterminateModel)

    RestrictionWrapper(restrictedMode, restrictedModel, content)
}

@Composable
private fun RestrictionWrapper(
    restrictedMode: RestrictedMode?,
    restrictedModel: SwitchPreferenceModel,
    content: @Composable (SwitchPreferenceModel, Modifier) -> Unit,
) {
    val modifier =
        when (restrictedMode) {
            is BlockedWithDetails -> {
                val statusDescription = stringResource(R.string.spa_unavailable)
                Modifier.clickable(
                        onClickLabel = stringResource(R.string.spa_learn_more),
                        role = Role.Switch,
                        onClick = { restrictedMode.showDetails() },
                    )
                    .semantics {
                        contentDescription = statusDescription
                        toggleableState = toggleableState(restrictedModel.checked())
                    }
            }

            else -> Modifier
        }
    content(restrictedModel, modifier)
}

    restrictedSwitchPreferenceModel.RestrictionWrapper(content)
private fun toggleableState(value: Boolean?) =
    when (value) {
        true -> ToggleableState.On
        false -> ToggleableState.Off
        null -> ToggleableState.Indeterminate
    }
+1 −2
Original line number Diff line number Diff line
@@ -25,8 +25,7 @@ import com.android.settingslib.spa.widget.preference.SwitchPreferenceModel
 * Restricted version [MainSwitchPreference].
 *
 * @param ifBlockedOverrideCheckedTo if this is not null and the current [RestrictedMode] is
 *   [Blocked] and [Blocked.canOverrideSwitchChecked] is set to true, the switch's checked status
 *   will be overridden to this value.
 *   [Blocked], the switch's checked status will be overridden to this value.
 */
@Composable
fun RestrictedMainSwitchPreference(
+25 −6
Original line number Diff line number Diff line
@@ -16,20 +16,39 @@

package com.android.settingslib.spa.restricted

import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flowOf

sealed interface RestrictedMode

data object NoRestricted : RestrictedMode

sealed interface Blocked : RestrictedMode {
    /**
     * Determines if the [RestrictedSwitchPreference]'s checked state will be forced to its param
     * value of `ifBlockedOverrideCheckedTo` when the preference is blocked.
     * Represents the configuration for overriding a [RestrictedSwitchPreference] or
     * [RestrictedMainSwitchPreference] when it's in a blocked state.
     *
     * Requires [RestrictedSwitchPreference]'s param `ifBlockedOverrideCheckedTo` to be set to a
     * specific state (true or false).
     * This class allows specifying whether the checked state of the preference should be overridden
     * and provides custom summaries for the 'on' and 'off' states when blocked.
     */
    val canOverrideSwitchChecked: Boolean
        get() = false
    data class SwitchPreferenceOverrides(
        /**
         * The summary to show when the preference is blocked and checked value is on.
         *
         * Note: Requires switch preference's param `ifBlockedOverrideCheckedTo` to be set to true.
         */
        val summaryOn: String? = null,

        /**
         * The summary to show when the preference is blocked and checked value is off.
         *
         * Note: Requires switch preference's param `ifBlockedOverrideCheckedTo` to be set to false.
         */
        val summaryOff: String? = null,
    )

    val switchPreferenceOverridesFlow: Flow<SwitchPreferenceOverrides>
        get() = flowOf(SwitchPreferenceOverrides())
}

interface BlockedWithDetails : Blocked {
Loading