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

Commit 852097f5 authored by Zekan Qian's avatar Zekan Qian Committed by Android (Google) Code Review
Browse files

Merge changes I05b50ace,Ic370f271

* changes:
  Add gallery page of item list operation
  Add arguments in displayName of page.
parents ce9816e8 5d3f6f39
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -24,6 +24,9 @@ import com.android.settingslib.spa.framework.common.createSettingsPage
import com.android.settingslib.spa.gallery.button.ActionButtonPageProvider
import com.android.settingslib.spa.gallery.dialog.AlterDialogPageProvider
import com.android.settingslib.spa.gallery.home.HomePageProvider
import com.android.settingslib.spa.gallery.itemList.ItemListPageProvider
import com.android.settingslib.spa.gallery.itemList.ItemOperatePageProvider
import com.android.settingslib.spa.gallery.itemList.OperateListPageProvider
import com.android.settingslib.spa.gallery.page.ArgumentPageProvider
import com.android.settingslib.spa.gallery.page.ChartPageProvider
import com.android.settingslib.spa.gallery.page.FooterPageProvider
@@ -50,6 +53,8 @@ enum class SettingsPageProviderEnum(val displayName: String) {
    HOME("home"),
    PREFERENCE("preference"),
    ARGUMENT("argument"),
    ITEM_LIST("itemList"),
    ITEM_OP_PAGE("itemOp"),

    // Add your SPPs
}
@@ -76,6 +81,9 @@ class GallerySpaEnvironment(context: Context) : SpaEnvironment(context) {
                LoadingBarPageProvider,
                ChartPageProvider,
                AlterDialogPageProvider,
                ItemListPageProvider,
                ItemOperatePageProvider,
                OperateListPageProvider,
            ),
            rootPages = listOf(
                HomePageProvider.createSettingsPage(),
+7 −2
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.settingslib.spa.gallery.home

import android.os.Bundle
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.tooling.preview.Preview
import com.android.settingslib.spa.framework.common.SettingsEntry
import com.android.settingslib.spa.framework.common.SettingsPageProvider
@@ -28,6 +29,7 @@ import com.android.settingslib.spa.gallery.R
import com.android.settingslib.spa.gallery.SettingsPageProviderEnum
import com.android.settingslib.spa.gallery.button.ActionButtonPageProvider
import com.android.settingslib.spa.gallery.dialog.AlterDialogPageProvider
import com.android.settingslib.spa.gallery.itemList.OperateListPageProvider
import com.android.settingslib.spa.gallery.page.ArgumentPageModel
import com.android.settingslib.spa.gallery.page.ArgumentPageProvider
import com.android.settingslib.spa.gallery.page.ChartPageProvider
@@ -50,6 +52,7 @@ object HomePageProvider : SettingsPageProvider {
    override fun buildEntry(arguments: Bundle?): List<SettingsEntry> {
        return listOf(
            PreferenceMainPageProvider.buildInjectEntry().setLink(fromPage = owner).build(),
            OperateListPageProvider.buildInjectEntry().setLink(fromPage = owner).build(),
            ArgumentPageProvider.buildInjectEntry("foo")!!.setLink(fromPage = owner).build(),
            SliderPageProvider.buildInjectEntry().setLink(fromPage = owner).build(),
            SpinnerPageProvider.buildInjectEntry().setLink(fromPage = owner).build(),
@@ -71,8 +74,10 @@ object HomePageProvider : SettingsPageProvider {

    @Composable
    override fun Page(arguments: Bundle?) {
        HomeScaffold(title = getTitle(arguments)) {
            for (entry in buildEntry(arguments)) {
        val title = remember { getTitle(arguments) }
        val entries = remember { buildEntry(arguments) }
        HomeScaffold(title) {
            for (entry in entries) {
                if (entry.owner.isCreateBy(SettingsPageProviderEnum.ARGUMENT.name)) {
                    entry.UiLayout(ArgumentPageModel.buildArgument(intParam = 0))
                } else {
+99 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 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.gallery.itemList

import android.os.Bundle
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.core.os.bundleOf
import androidx.navigation.NavType
import androidx.navigation.navArgument
import com.android.settingslib.spa.framework.common.EntrySearchData
import com.android.settingslib.spa.framework.common.SettingsEntry
import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
import com.android.settingslib.spa.framework.common.SettingsPageProvider
import com.android.settingslib.spa.framework.common.createSettingsPage
import com.android.settingslib.spa.framework.compose.navigator
import com.android.settingslib.spa.framework.util.getStringArg
import com.android.settingslib.spa.framework.util.navLink
import com.android.settingslib.spa.gallery.SettingsPageProviderEnum
import com.android.settingslib.spa.widget.preference.Preference
import com.android.settingslib.spa.widget.preference.PreferenceModel
import com.android.settingslib.spa.widget.scaffold.RegularScaffold

private const val OPERATOR_PARAM_NAME = "opParam"

object ItemListPageProvider : SettingsPageProvider {
    override val name = SettingsPageProviderEnum.ITEM_LIST.name
    override val displayName = SettingsPageProviderEnum.ITEM_LIST.displayName
    override val parameter = listOf(
        navArgument(OPERATOR_PARAM_NAME) { type = NavType.StringType },
    )

    override fun getTitle(arguments: Bundle?): String {
        val operation = parameter.getStringArg(OPERATOR_PARAM_NAME, arguments) ?: "NULL"
        return "Operation: $operation"
    }

    override fun buildEntry(arguments: Bundle?): List<SettingsEntry> {
        if (!ItemOperatePageProvider.isValidArgs(arguments)) return emptyList()
        val operation = parameter.getStringArg(OPERATOR_PARAM_NAME, arguments)!!
        val owner = createSettingsPage(arguments)
        return listOf(
            ItemOperatePageProvider.buildInjectEntry(operation)!!.setLink(fromPage = owner).build(),
        )
    }

    fun buildInjectEntry(opParam: String): SettingsEntryBuilder? {
        val arguments = bundleOf(OPERATOR_PARAM_NAME to opParam)
        if (!ItemOperatePageProvider.isValidArgs(arguments)) return null

        return SettingsEntryBuilder.createInject(
            owner = createSettingsPage(arguments),
            displayName = "ItemList_$opParam",
        ).setUiLayoutFn {
            Preference(
                object : PreferenceModel {
                    override val title = opParam
                    override val onClick = navigator(
                        SettingsPageProviderEnum.ITEM_LIST.name + parameter.navLink(it)
                    )
                }
            )
        }.setSearchDataFn {
            EntrySearchData(title = "Operation: $opParam")
        }
    }

    @Composable
    override fun Page(arguments: Bundle?) {
        val title = remember { getTitle(arguments) }
        val entries = remember { buildEntry(arguments) }
        val itemList = remember {
            // Add logic to get item List during runtime.
            listOf("itemFoo", "itemBar", "itemToy")
        }
        RegularScaffold(title) {
            for (item in itemList) {
                val rtArgs = ItemOperatePageProvider.genRuntimeArguments(item)
                for (entry in entries) {
                    entry.UiLayout(rtArgs)
                }
            }
        }
    }
}
+125 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 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.gallery.itemList

import android.os.Bundle
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.core.os.bundleOf
import androidx.navigation.NavType
import androidx.navigation.navArgument
import com.android.settingslib.spa.framework.common.SettingsEntry
import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
import com.android.settingslib.spa.framework.common.SettingsPageProvider
import com.android.settingslib.spa.framework.common.createSettingsPage
import com.android.settingslib.spa.framework.compose.navigator
import com.android.settingslib.spa.framework.util.getStringArg
import com.android.settingslib.spa.framework.util.navLink
import com.android.settingslib.spa.gallery.SettingsPageProviderEnum
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

private const val OPERATOR_PARAM_NAME = "opParam"
private const val ITEM_NAME_PARAM_NAME = "rt_nameParam"
private val ALLOWED_OPERATOR_LIST = listOf("opDnD", "opPiP", "opInstall", "opConnect")

object ItemOperatePageProvider : SettingsPageProvider {
    override val name = SettingsPageProviderEnum.ITEM_OP_PAGE.name
    override val displayName = SettingsPageProviderEnum.ITEM_OP_PAGE.displayName
    override val parameter = listOf(
        navArgument(OPERATOR_PARAM_NAME) { type = NavType.StringType },
        navArgument(ITEM_NAME_PARAM_NAME) { type = NavType.StringType },
    )

    override fun getTitle(arguments: Bundle?): String {
        // Operation name is not a runtime parameter, which should always available
        val operation = parameter.getStringArg(OPERATOR_PARAM_NAME, arguments) ?: "opInValid"
        // Item name is a runtime parameter, which could be missing
        val itemName = parameter.getStringArg(ITEM_NAME_PARAM_NAME, arguments) ?: "[unset]"
        return "$operation on $itemName"
    }

    override fun buildEntry(arguments: Bundle?): List<SettingsEntry> {
        if (!isValidArgs(arguments)) return emptyList()

        val owner = createSettingsPage(arguments)
        val entryList = mutableListOf<SettingsEntry>()
        entryList.add(
            SettingsEntryBuilder.create("ItemName", owner)
                .setUiLayoutFn {
                    // Item name is a runtime parameter, which needs to be read inside UiLayoutFn
                    val itemName = parameter.getStringArg(ITEM_NAME_PARAM_NAME, it) ?: "NULL"
                    Preference(
                        object : PreferenceModel {
                            override val title = "Item $itemName"
                        }
                    )
                }.build()
        )

        // Operation name is not a runtime parameter, which can be read outside.
        val opName = parameter.getStringArg(OPERATOR_PARAM_NAME, arguments)!!
        entryList.add(
            SettingsEntryBuilder.create("ItemOp", owner)
                .setUiLayoutFn {
                    val checked = rememberSaveable { mutableStateOf(false) }
                    SwitchPreference(remember {
                        object : SwitchPreferenceModel {
                            override val title = "Item operation: $opName"
                            override val checked = checked
                            override val onCheckedChange =
                                { newChecked: Boolean -> checked.value = newChecked }
                        }
                    })
                }.build(),
        )
        return entryList
    }

    fun buildInjectEntry(opParam: String): SettingsEntryBuilder? {
        val arguments = bundleOf(OPERATOR_PARAM_NAME to opParam)
        if (!isValidArgs(arguments)) return null

        return SettingsEntryBuilder.createInject(
            owner = createSettingsPage(arguments),
            displayName = "ItemOp_$opParam",
        ).setUiLayoutFn {
            // Item name is a runtime parameter, which needs to be read inside UiLayoutFn
            val itemName = parameter.getStringArg(ITEM_NAME_PARAM_NAME, it) ?: "NULL"
            Preference(
                object : PreferenceModel {
                    override val title = "item: $itemName"
                    override val onClick = navigator(
                        SettingsPageProviderEnum.ITEM_OP_PAGE.name + parameter.navLink(it)
                    )
                }
            )
        }
    }

    fun isValidArgs(arguments: Bundle?): Boolean {
        val opParam = parameter.getStringArg(OPERATOR_PARAM_NAME, arguments)
        return (opParam != null && ALLOWED_OPERATOR_LIST.contains(opParam))
    }

    fun genRuntimeArguments(itemName: String): Bundle {
        return bundleOf(ITEM_NAME_PARAM_NAME to itemName)
    }
}
+56 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 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.gallery.itemList

import android.os.Bundle
import com.android.settingslib.spa.framework.common.SettingsEntry
import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
import com.android.settingslib.spa.framework.common.SettingsPageProvider
import com.android.settingslib.spa.framework.common.createSettingsPage
import com.android.settingslib.spa.framework.compose.navigator
import com.android.settingslib.spa.widget.preference.Preference
import com.android.settingslib.spa.widget.preference.PreferenceModel

private const val TITLE = "Operate List Main"

object OperateListPageProvider : SettingsPageProvider {
    override val name = "OpList"
    private val owner = createSettingsPage()

    override fun buildEntry(arguments: Bundle?): List<SettingsEntry> {
        return listOf(
            ItemListPageProvider.buildInjectEntry("opPiP")!!.setLink(fromPage = owner).build(),
            ItemListPageProvider.buildInjectEntry("opInstall")!!.setLink(fromPage = owner).build(),
            ItemListPageProvider.buildInjectEntry("opDnD")!!.setLink(fromPage = owner).build(),
            ItemListPageProvider.buildInjectEntry("opConnect")!!.setLink(fromPage = owner).build(),
        )
    }

    override fun getTitle(arguments: Bundle?): String {
        return TITLE
    }

    fun buildInjectEntry(): SettingsEntryBuilder {
        return SettingsEntryBuilder.createInject(owner = owner)
            .setUiLayoutFn {
                Preference(object : PreferenceModel {
                    override val title = TITLE
                    override val onClick = navigator(name)
                })
            }
    }
}
Loading