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

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

Merge "[Spa] Add RestrictedMainSwitchPreference" into main

parents 36a18353 2daa9e05
Loading
Loading
Loading
Loading
+40 −12
Original line number Diff line number Diff line
@@ -25,10 +25,11 @@ import androidx.compose.runtime.setValue
import androidx.lifecycle.compose.collectAsStateWithLifecycle
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.preference.MainSwitchPreference
import com.android.settingslib.spa.widget.preference.Preference
import com.android.settingslib.spa.widget.preference.PreferenceModel
import com.android.settingslib.spa.widget.preference.SwitchPreference
import com.android.settingslib.spa.widget.preference.SwitchPreferenceModel
import com.android.settingslib.spa.widget.scaffold.RegularScaffold
import com.android.settingslib.spa.widget.ui.Category
@@ -41,8 +42,13 @@ object RestrictedSwitchPreferencePageProvider : SettingsPageProvider {
    @Composable
    override fun Page(arguments: Bundle?) {
        RegularScaffold(TITLE) {
            Category {
            EnableRestrictionsSwitchPreference()

            SampleRestrictedMainSwitchPreference(ifBlockedOverrideCheckedTo = null)
            SampleRestrictedMainSwitchPreference(ifBlockedOverrideCheckedTo = true)
            SampleRestrictedMainSwitchPreference(ifBlockedOverrideCheckedTo = false)

            Category {
                SampleRestrictedSwitchPreference(ifBlockedOverrideCheckedTo = null)
                SampleRestrictedSwitchPreference(ifBlockedOverrideCheckedTo = true)
                SampleRestrictedSwitchPreference(ifBlockedOverrideCheckedTo = false)
@@ -65,7 +71,7 @@ object RestrictedSwitchPreferencePageProvider : SettingsPageProvider {
private fun EnableRestrictionsSwitchPreference() {
    val enableRestrictions by
        GalleryRestrictedRepository.enableRestrictionsFlow.collectAsStateWithLifecycle()
    SwitchPreference(
    MainSwitchPreference(
        model =
            object : SwitchPreferenceModel {
                override val title = "Enable restrictions"
@@ -77,20 +83,42 @@ private fun EnableRestrictionsSwitchPreference() {
    )
}

@Composable
private fun SampleRestrictedMainSwitchPreference(ifBlockedOverrideCheckedTo: Boolean?) {
    RestrictedMainSwitchPreference(
        model =
            createSwitchPreferenceModel(
                title = "RestrictedMainSwitchPreference",
                ifBlockedOverrideCheckedTo = ifBlockedOverrideCheckedTo,
            ),
        restrictions = GalleryRestrictions(isRestricted = true),
        ifBlockedOverrideCheckedTo = ifBlockedOverrideCheckedTo,
    )
}

@Composable
private fun SampleRestrictedSwitchPreference(ifBlockedOverrideCheckedTo: Boolean?) {
    var checked by rememberSaveable { mutableStateOf(false) }
    RestrictedSwitchPreference(
        model =
            object : SwitchPreferenceModel {
                override val title = "RestrictedSwitchPreference"
                override val summary = {
                    "ifBlockedOverrideCheckedTo = $ifBlockedOverrideCheckedTo"
                }
                override val checked = { checked }
                override val onCheckedChange = { newChecked: Boolean -> checked = newChecked }
            },
            createSwitchPreferenceModel(
                title = "RestrictedSwitchPreference",
                ifBlockedOverrideCheckedTo = ifBlockedOverrideCheckedTo,
            ),
        restrictions = GalleryRestrictions(isRestricted = true),
        ifBlockedOverrideCheckedTo = ifBlockedOverrideCheckedTo,
    )
}

@Composable
private fun createSwitchPreferenceModel(
    title: String,
    ifBlockedOverrideCheckedTo: Boolean?,
): SwitchPreferenceModel {
    var checked by rememberSaveable { mutableStateOf(false) }
    return object : SwitchPreferenceModel {
        override val title = title
        override val summary = { "ifBlockedOverrideCheckedTo = $ifBlockedOverrideCheckedTo" }
        override val checked = { checked }
        override val onCheckedChange = { newChecked: Boolean -> checked = newChecked }
    }
}
+69 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.settingslib.spa.restricted

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.lifecycle.compose.collectAsStateWithLifecycle
import com.android.settingslib.spa.framework.common.SpaEnvironmentFactory
import com.android.settingslib.spa.widget.preference.SwitchPreferenceModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.flowOn

@Composable
internal fun rememberRestrictedRepository(): RestrictedRepository {
    val context = LocalContext.current
    val repository = remember {
        checkNotNull(SpaEnvironmentFactory.instance.getRestrictedRepository(context)) {
            "RestrictedRepository not set"
        }
    }
    return repository
}

@Composable
internal fun RestrictedBaseSwitchPreference(
    model: SwitchPreferenceModel,
    restrictions: Restrictions,
    repository: RestrictedRepository,
    ifBlockedOverrideCheckedTo: Boolean? = null,
    content: @Composable (SwitchPreferenceModel, Modifier) -> Unit,
) {
    if (restrictions.isEmpty()) {
        content(model, Modifier)
        return
    }
    val restrictedModeFlow =
        remember(restrictions) {
            repository.restrictedModeFlow(restrictions).flowOn(Dispatchers.Default)
        }
    val restrictedMode by
        restrictedModeFlow.collectAsStateWithLifecycle(initialValue = NoRestricted)
    val restrictedSwitchPreferenceModel =
        remember(restrictedMode, model, ifBlockedOverrideCheckedTo) {
            RestrictedSwitchPreferenceModel(
                model = model,
                restrictedMode = restrictedMode,
                ifBlockedOverrideCheckedTo = ifBlockedOverrideCheckedTo,
            )
        }

    restrictedSwitchPreferenceModel.RestrictionWrapper(content)
}
+57 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.settingslib.spa.restricted

import androidx.annotation.VisibleForTesting
import androidx.compose.runtime.Composable
import com.android.settingslib.spa.widget.preference.MainSwitchPreference
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.
 */
@Composable
fun RestrictedMainSwitchPreference(
    model: SwitchPreferenceModel,
    restrictions: Restrictions,
    ifBlockedOverrideCheckedTo: Boolean? = null,
) {
    val repository = rememberRestrictedRepository()
    RestrictedMainSwitchPreference(model, restrictions, repository, ifBlockedOverrideCheckedTo)
}

@VisibleForTesting
@Composable
internal fun RestrictedMainSwitchPreference(
    model: SwitchPreferenceModel,
    restrictions: Restrictions,
    repository: RestrictedRepository,
    ifBlockedOverrideCheckedTo: Boolean? = null,
) {
    RestrictedBaseSwitchPreference(
        model = model,
        restrictions = restrictions,
        repository = repository,
        ifBlockedOverrideCheckedTo = ifBlockedOverrideCheckedTo,
    ) { model, modifier ->
        MainSwitchPreference(model, modifier)
    }
}
+8 −32
Original line number Diff line number Diff line
@@ -18,15 +18,8 @@ package com.android.settingslib.spa.restricted

import androidx.annotation.VisibleForTesting
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalContext
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.android.settingslib.spa.framework.common.SpaEnvironmentFactory
import com.android.settingslib.spa.widget.preference.SwitchPreference
import com.android.settingslib.spa.widget.preference.SwitchPreferenceModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.flowOn

/**
 * Restricted version [SwitchPreference].
@@ -41,12 +34,7 @@ fun RestrictedSwitchPreference(
    restrictions: Restrictions,
    ifBlockedOverrideCheckedTo: Boolean? = null,
) {
    val context = LocalContext.current
    val repository = remember {
        checkNotNull(SpaEnvironmentFactory.instance.getRestrictedRepository(context)) {
            "RestrictedRepository not set"
        }
    }
    val repository = rememberRestrictedRepository()
    RestrictedSwitchPreference(model, restrictions, repository, ifBlockedOverrideCheckedTo)
}

@@ -58,24 +46,12 @@ internal fun RestrictedSwitchPreference(
    repository: RestrictedRepository,
    ifBlockedOverrideCheckedTo: Boolean? = null,
) {
    if (restrictions.isEmpty()) {
        SwitchPreference(model)
        return
    }
    val restrictedModeFlow =
        remember(restrictions) {
            repository.restrictedModeFlow(restrictions).flowOn(Dispatchers.Default)
        }
    val restrictedMode by
        restrictedModeFlow.collectAsStateWithLifecycle(initialValue = NoRestricted)
    val restrictedSwitchPreferenceModel =
        remember(restrictedMode, model, ifBlockedOverrideCheckedTo) {
            RestrictedSwitchPreferenceModel(
    RestrictedBaseSwitchPreference(
        model = model,
                restrictedMode = restrictedMode,
        restrictions = restrictions,
        repository = repository,
        ifBlockedOverrideCheckedTo = ifBlockedOverrideCheckedTo,
            )
    ) { model, modifier ->
        SwitchPreference(model, modifier)
    }

    restrictedSwitchPreferenceModel.RestrictionWrapper { SwitchPreference(it) }
}
+2 −3
Original line number Diff line number Diff line
@@ -17,7 +17,6 @@
package com.android.settingslib.spa.restricted

import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.semantics.Role
@@ -59,7 +58,7 @@ internal class RestrictedSwitchPreferenceModel(
        }

    @Composable
    fun RestrictionWrapper(content: @Composable (SwitchPreferenceModel) -> Unit) {
    fun RestrictionWrapper(content: @Composable (SwitchPreferenceModel, Modifier) -> Unit) {
        val modifier =
            when (restrictedMode) {
                is BlockedWithDetails -> {
@@ -72,7 +71,7 @@ internal class RestrictedSwitchPreferenceModel(

                else -> Modifier
            }
        Box(modifier) { content(this@RestrictedSwitchPreferenceModel) }
        content(this, modifier)
    }

    companion object {
Loading