Add SettingsEntryRepository with some refactoring

1. Refactor SpaEnvironment, lazy init sppRepo and entryRepo
2. Add SettingsArguments with helper functions for arguments build, which is going to replace arguments in SPP
3. Add rootSettingsPages in SppRepo, which is going to replace rootPageNames (TODO).
4. Add button in HomePage to print pages & entries

Bug: 244122804
Test: manual - build Spa gallery
Change-Id: Iccc66f0cb7156c8aa2d9793e296c2a1a2b0e277a
This commit is contained in:
Zekan Qian
2022-09-02 16:36:19 +08:00
parent 44622764d9
commit dccbbc0b58
13 changed files with 325 additions and 189 deletions

View File

@@ -18,4 +18,4 @@ package com.android.settingslib.spa.gallery
import com.android.settingslib.spa.framework.BrowseActivity
class MainActivity : BrowseActivity(galleryPageProviders)
class MainActivity : BrowseActivity(SpaEnvironment.PageProviderRepository)

View File

@@ -16,6 +16,8 @@
package com.android.settingslib.spa.gallery
import com.android.settingslib.spa.framework.common.SettingsEntryRepository
import com.android.settingslib.spa.framework.common.SettingsPage
import com.android.settingslib.spa.framework.common.SettingsPageProviderRepository
import com.android.settingslib.spa.gallery.home.HomePageProvider
import com.android.settingslib.spa.gallery.page.ArgumentPageProvider
@@ -28,20 +30,39 @@ import com.android.settingslib.spa.gallery.preference.SwitchPreferencePageProvid
import com.android.settingslib.spa.gallery.preference.TwoTargetSwitchPreferencePageProvider
import com.android.settingslib.spa.gallery.ui.SpinnerPageProvider
val galleryPageProviders = SettingsPageProviderRepository(
allPagesList = listOf(
HomePageProvider,
PreferenceMainPageProvider,
PreferencePageProvider,
SwitchPreferencePageProvider,
TwoTargetSwitchPreferencePageProvider,
ArgumentPageProvider,
SliderPageProvider,
SpinnerPageProvider,
SettingsPagerPageProvider,
FooterPageProvider,
),
rootPages = listOf(HomePageProvider.name)
)
object SpaEnvironment {
val PageProviderRepository: SettingsPageProviderRepository by
lazy(LazyThreadSafetyMode.SYNCHRONIZED) {
SettingsPageProviderRepository(
allPagesList = listOf(
HomePageProvider,
PreferenceMainPageProvider,
PreferencePageProvider,
SwitchPreferencePageProvider,
TwoTargetSwitchPreferencePageProvider,
ArgumentPageProvider,
SliderPageProvider,
SpinnerPageProvider,
SettingsPagerPageProvider,
FooterPageProvider,
),
rootPageData = listOf(
SettingsPage(HomePageProvider.name),
SettingsPage(
ArgumentPageProvider.name,
ArgumentPageProvider.buildArgument("foo")
),
SettingsPage(
ArgumentPageProvider.name,
ArgumentPageProvider.buildArgument("bar")
),
)
)
}
// TODO: add other environment setup here.
val EntryRepository: SettingsEntryRepository by lazy(LazyThreadSafetyMode.SYNCHRONIZED) {
SettingsEntryRepository(PageProviderRepository)
}
// TODO: add other environment setup here.
}

View File

@@ -17,12 +17,15 @@
package com.android.settingslib.spa.gallery.home
import android.os.Bundle
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import com.android.settingslib.spa.framework.common.SettingsPageProvider
import com.android.settingslib.spa.framework.theme.SettingsTheme
import com.android.settingslib.spa.gallery.R
import com.android.settingslib.spa.gallery.SpaEnvironment
import com.android.settingslib.spa.gallery.page.ArgumentPageProvider
import com.android.settingslib.spa.gallery.page.FooterPageProvider
import com.android.settingslib.spa.gallery.page.SettingsPagerPageProvider
@@ -50,6 +53,17 @@ private fun HomePage() {
SpinnerPageProvider.EntryItem()
SettingsPagerPageProvider.EntryItem()
FooterPageProvider.EntryItem()
/**
* A test button to generate hierarchy.
* TODO: remove it once the content provider is ready.
*/
Button(onClick = {
SpaEnvironment.EntryRepository.printAllPages()
SpaEnvironment.EntryRepository.printAllEntries()
}) {
Text(text = "Generate Entry")
}
}
}

View File

@@ -19,16 +19,20 @@ package com.android.settingslib.spa.gallery.page
import android.os.Bundle
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import androidx.navigation.NamedNavArgument
import androidx.navigation.NavType
import androidx.navigation.navArgument
import com.android.settingslib.spa.framework.common.PageArguments
import com.android.settingslib.spa.framework.common.SettingsEntry
import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
import com.android.settingslib.spa.framework.common.SettingsPageBuilder
import com.android.settingslib.spa.framework.common.SettingsPage
import com.android.settingslib.spa.framework.common.SettingsPageProvider
import com.android.settingslib.spa.framework.compose.navigator
import com.android.settingslib.spa.framework.compose.toState
import com.android.settingslib.spa.framework.theme.SettingsTheme
import com.android.settingslib.spa.framework.util.getIntArg
import com.android.settingslib.spa.framework.util.getStringArg
import com.android.settingslib.spa.framework.util.navLink
import com.android.settingslib.spa.framework.util.normalize
import com.android.settingslib.spa.widget.preference.Preference
import com.android.settingslib.spa.widget.preference.PreferenceModel
import com.android.settingslib.spa.widget.scaffold.RegularScaffold
@@ -40,22 +44,22 @@ private const val INT_PARAM_NAME = "intParam"
object ArgumentPageProvider : SettingsPageProvider {
override val name = "Argument"
override val arguments = listOf(
override val parameter = listOf(
navArgument(STRING_PARAM_NAME) { type = NavType.StringType },
navArgument(INT_PARAM_NAME) { type = NavType.IntType },
)
override fun buildEntry(arguments: Bundle?): List<SettingsEntry> {
val pageArgs = PageArguments(ArgumentPageProvider.arguments, arguments)
if (!pageArgs.isValid()) return emptyList()
if (!parameter.isValid(arguments)) return emptyList()
val owner = SettingsPageBuilder.create(name, pageArgs.normalize()).build()
val owner = SettingsPage(name, parameter.normalize(arguments))
val entryList = mutableListOf<SettingsEntry>()
val stringParamEntry = SettingsEntryBuilder.create("string_param", owner)
stringParamEntry.setUiLayoutFn {
Preference(object : PreferenceModel {
override val title = "String param value"
override val summary = pageArgs.getStringArg(STRING_PARAM_NAME)!!.toState()
override val summary =
parameter.getStringArg(STRING_PARAM_NAME, arguments)!!.toState()
})
}
entryList.add(stringParamEntry.build())
@@ -64,13 +68,15 @@ object ArgumentPageProvider : SettingsPageProvider {
intParamEntry.setUiLayoutFn {
Preference(object : PreferenceModel {
override val title = "Int param value"
override val summary = pageArgs.getIntArg(INT_PARAM_NAME)!!.toString().toState()
override val summary =
parameter.getIntArg(INT_PARAM_NAME, arguments)!!.toString().toState()
})
}
entryList.add(intParamEntry.build())
val entryFoo = buildInjectEntry(pageArgs.buildNextArg("foo"))
val entryBar = buildInjectEntry(pageArgs.buildNextArg("bar"))
val intParam = parameter.getIntArg(INT_PARAM_NAME, arguments)
val entryFoo = buildInjectEntry(buildNextArgument("foo", intParam))
val entryBar = buildInjectEntry(buildNextArgument("bar", intParam))
if (entryFoo != null) entryList.add(entryFoo.setLink(fromPage = owner).build())
if (entryBar != null) entryList.add(entryBar.setLink(fromPage = owner).build())
@@ -78,21 +84,21 @@ object ArgumentPageProvider : SettingsPageProvider {
}
private fun buildInjectEntry(arguments: Bundle?): SettingsEntryBuilder? {
val pageArgs = PageArguments(ArgumentPageProvider.arguments, arguments)
if (!pageArgs.isValid()) return null
if (!parameter.isValid(arguments)) return null
val seBuilder = SettingsEntryBuilder.createLinkTo("injection", name, pageArgs.normalize())
val seBuilder =
SettingsEntryBuilder.createInject(name, parameter.normalize(arguments))
seBuilder.setIsAllowSearch(false)
seBuilder.setUiLayoutFn {
val summaryArray = listOf(
"$STRING_PARAM_NAME=" + pageArgs.getStringArg(STRING_PARAM_NAME)!!,
"$INT_PARAM_NAME=" + pageArgs.getIntArg(INT_PARAM_NAME)!!
"$STRING_PARAM_NAME=" + parameter.getStringArg(STRING_PARAM_NAME, arguments)!!,
"$INT_PARAM_NAME=" + parameter.getIntArg(INT_PARAM_NAME, arguments)!!
)
Preference(object : PreferenceModel {
override val title = TITLE
override val summary = summaryArray.joinToString(", ").toState()
override val onClick = navigator(name + pageArgs.navLink())
override val onClick = navigator(name + parameter.navLink(arguments))
})
}
@@ -112,32 +118,33 @@ object ArgumentPageProvider : SettingsPageProvider {
fun EntryItem(stringParam: String, intParam: Int) {
buildInjectEntry(buildArgument(stringParam, intParam))?.build()?.uiLayout?.let { it() }
}
fun buildArgument(stringParam: String, intParam: Int? = null): Bundle {
val args = Bundle()
args.putString(STRING_PARAM_NAME, stringParam)
if (intParam != null) args.putInt(INT_PARAM_NAME, intParam)
return args
}
private fun buildNextArgument(stringParam: String, intParam: Int? = null): Bundle {
return if (intParam == null)
buildArgument(stringParam)
else
buildArgument(stringParam, intParam + 1)
}
}
@Preview(showBackground = true)
@Composable
private fun ArgumentPagePreview() {
SettingsTheme {
ArgumentPageProvider.Page(buildArgument(stringParam = "foo", intParam = 0))
ArgumentPageProvider.Page(
ArgumentPageProvider.buildArgument(stringParam = "foo", intParam = 0)
)
}
}
private fun PageArguments.isValid(): Boolean {
val stringParam = getStringArg(STRING_PARAM_NAME)
private fun List<NamedNavArgument>.isValid(arguments: Bundle?): Boolean {
val stringParam = getStringArg(STRING_PARAM_NAME, arguments)
return (stringParam != null && listOf("foo", "bar").contains(stringParam))
}
private fun PageArguments.buildNextArg(stringParam: String): Bundle {
val intParam = getIntArg(INT_PARAM_NAME)
return if (intParam == null)
buildArgument(stringParam)
else
buildArgument(stringParam, intParam + 1)
}
private fun buildArgument(stringParam: String, intParam: Int? = null): Bundle {
val args = Bundle()
args.putString(STRING_PARAM_NAME, stringParam)
if (intParam != null) args.putInt(INT_PARAM_NAME, intParam)
return args
}

View File

@@ -27,10 +27,10 @@ import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import com.android.settingslib.spa.R
import com.android.settingslib.spa.framework.common.SettingsPageProvider
import com.android.settingslib.spa.framework.common.SettingsPageProviderRepository
import com.android.settingslib.spa.framework.compose.localNavController
import com.android.settingslib.spa.framework.theme.SettingsTheme
import com.android.settingslib.spa.framework.util.navRoute
open class BrowseActivity(
private val sppRepository: SettingsPageProviderRepository,
@@ -55,8 +55,8 @@ open class BrowseActivity(
NavHost(navController, sppRepository.getDefaultStartPageName()) {
for (page in sppRepository.getAllProviders()) {
composable(
route = page.route,
arguments = page.arguments,
route = page.name + page.parameter.navRoute(),
arguments = page.parameter,
) { navBackStackEntry ->
page.Page(navBackStackEntry.arguments)
}
@@ -75,9 +75,6 @@ open class BrowseActivity(
}
}
private val SettingsPageProvider.route: String
get() = name + arguments.joinToString("") { argument -> "/{${argument.name}}" }
companion object {
const val KEY_DESTINATION = "spa:SpaActivity:destination"
}

View File

@@ -1,74 +0,0 @@
/*
* Copyright (C) 2022 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.framework.common
import android.os.Bundle
import androidx.navigation.NamedNavArgument
import androidx.navigation.NavType
class PageArguments(
private val navArgsDef: List<NamedNavArgument>,
private val rawArgs: Bundle?
) {
fun normalize(): Bundle {
if (rawArgs == null) return Bundle.EMPTY
val normArgs = Bundle()
for (navArg in navArgsDef) {
when (navArg.argument.type) {
NavType.StringType -> {
val value = rawArgs.getString(navArg.name)
if (value != null) normArgs.putString(navArg.name, value)
}
NavType.IntType -> {
if (rawArgs.containsKey(navArg.name))
normArgs.putInt(navArg.name, rawArgs.getInt(navArg.name))
}
}
}
return normArgs
}
fun navLink(): String{
if (rawArgs == null) return ""
val argsArray = mutableListOf<String>()
for (navArg in navArgsDef) {
when (navArg.argument.type) {
NavType.StringType -> {
argsArray.add(rawArgs.getString(navArg.name, ""))
}
NavType.IntType -> {
argsArray.add(rawArgs.getInt(navArg.name).toString())
}
}
}
return argsArray.joinToString("") {arg -> "/$arg" }
}
fun getStringArg(key: String): String? {
if (rawArgs != null && rawArgs.containsKey(key)) {
return rawArgs.getString(key)
}
return null
}
fun getIntArg(key: String): Int? {
if (rawArgs != null && rawArgs.containsKey(key)) {
return rawArgs.getInt(key)
}
return null
}
}

View File

@@ -19,6 +19,9 @@ package com.android.settingslib.spa.framework.common
import android.os.Bundle
import androidx.compose.runtime.Composable
const val INJECT_ENTRY_NAME = "INJECT"
const val ROOT_ENTRY_NAME = "ROOT"
/**
* Defines data of one Settings entry for Settings search.
*/
@@ -32,18 +35,22 @@ data class UiData(val title: String = "")
/**
* Defines data to identify a Settings page.
*/
data class SettingsPage(val name: String = "", val args: Bundle = Bundle.EMPTY)
data class SettingsPage(val name: String = "", val args: Bundle? = null) {
override fun toString(): String {
return name + args?.toString()
}
}
/**
* Defines data of a Settings entry.
*/
data class SettingsEntry(
// The unique id of this entry
val id: String,
val name: String,
val owner: SettingsPage,
// Generates the unique id of this entry
val uniqueId: String,
// Defines linking of Settings entries
val fromPage: SettingsPage? = null,
val toPage: SettingsPage? = null,
@@ -80,39 +87,13 @@ data class SettingsEntry(
* use each entries' UI rendering function in the page instead.
*/
val uiLayout: (@Composable () -> Unit) = {},
)
/**
* The helper to build a Settings Page instance.
*/
class SettingsPageBuilder(private val name: String) {
private val arguments = Bundle()
fun pushArgs(args: Bundle?): SettingsPageBuilder {
if (args != null) arguments.putAll(args)
return this
}
fun pushArg(argName: String, argValue: String?): SettingsPageBuilder {
if (argValue != null) this.arguments.putString(argName, argValue)
return this
}
fun pushArg(argName: String, argValue: Int?): SettingsPageBuilder {
if (argValue != null) this.arguments.putInt(argName, argValue)
return this
}
fun build(): SettingsPage {
return SettingsPage(name, arguments)
}
companion object {
fun create(name: String, args: Bundle? = null): SettingsPageBuilder {
return SettingsPageBuilder(name).apply {
pushArgs(args)
}
}
) {
override fun toString(): String {
return listOf(
name,
owner.toString(),
"(${fromPage?.toString()}-${toPage?.toString()})"
).joinToString("-")
}
}
@@ -130,9 +111,9 @@ class SettingsEntryBuilder(private val name: String, private val owner: Settings
fun build(): SettingsEntry {
return SettingsEntry(
id = computeUniqueId(),
name = name,
owner = owner,
uniqueId = computeUniqueId(),
// linking data
fromPage = fromPage,
@@ -171,22 +152,27 @@ class SettingsEntryBuilder(private val name: String, private val owner: Settings
return this
}
private fun computeUniqueId(): String = uniqueId ?: (name + owner.toString())
private fun computeUniqueId(): String =
uniqueId ?: name + owner.toString() + fromPage?.toString() + toPage?.toString()
private fun computeSearchable(): Boolean = isAllowSearch ?: false
companion object {
fun create(entryName: String, owner: SettingsPage): SettingsEntryBuilder {
return SettingsEntryBuilder(entryName, owner)
}
fun create(
entryName: String,
ownerPageName: String,
ownerPageArgs: Bundle? = null
): SettingsEntryBuilder {
val owner = SettingsPageBuilder.create(ownerPageName, ownerPageArgs)
return SettingsEntryBuilder(entryName, owner.build())
val owner = SettingsPage(ownerPageName, ownerPageArgs)
return create(entryName, owner)
}
fun create(entryName: String, owner: SettingsPage): SettingsEntryBuilder {
return SettingsEntryBuilder(entryName, owner)
fun createLinkTo(entryName: String, owner: SettingsPage): SettingsEntryBuilder {
return create(entryName, owner).setLink(toPage = owner)
}
fun createLinkTo(
@@ -194,12 +180,19 @@ class SettingsEntryBuilder(private val name: String, private val owner: Settings
ownerPageName: String,
ownerPageArgs: Bundle? = null
): SettingsEntryBuilder {
val owner = SettingsPageBuilder.create(ownerPageName, ownerPageArgs)
return SettingsEntryBuilder(entryName, owner.build()).setLink(toPage = owner.build())
val owner = SettingsPage(ownerPageName, ownerPageArgs)
return createLinkTo(entryName, owner)
}
fun createLinkTo(entryName: String, owner: SettingsPage): SettingsEntryBuilder {
return SettingsEntryBuilder(entryName, owner).setLink(toPage = owner)
fun createInject(
ownerPageName: String,
ownerPageArgs: Bundle? = null
): SettingsEntryBuilder {
return createLinkTo(INJECT_ENTRY_NAME, ownerPageName, ownerPageArgs)
}
fun createRoot(page: SettingsPage): SettingsEntryBuilder {
return createLinkTo(ROOT_ENTRY_NAME, page)
}
}
}

View File

@@ -0,0 +1,79 @@
/*
* Copyright (C) 2022 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.framework.common
import android.util.Log
import java.util.LinkedList
const val MAX_ENTRY_SIZE = 5000
/**
* The repository to maintain all Settings entries
*/
class SettingsEntryRepository(sppRepository: SettingsPageProviderRepository) {
// Map of entry unique Id to entry
private val entryMap: Map<String, SettingsEntry>
// Map of Settings page to its contained entries.
private val pageToEntryListMap: Map<String, List<SettingsEntry>>
init {
logMsg("Initialize")
entryMap = mutableMapOf()
pageToEntryListMap = mutableMapOf()
val entryQueue = LinkedList<SettingsEntry>()
for (page in sppRepository.getAllRootPages()) {
val rootEntry = SettingsEntryBuilder.createRoot(page).build()
if (!entryMap.containsKey(rootEntry.id)) {
entryQueue.push(rootEntry)
entryMap.put(rootEntry.id, rootEntry)
}
}
while (entryQueue.isNotEmpty() && entryMap.size < MAX_ENTRY_SIZE) {
val entry = entryQueue.pop()
val page = entry.toPage
if (page == null || pageToEntryListMap.containsKey(page.toString())) continue
val spp = sppRepository.getProviderOrNull(page.name) ?: continue
val newEntries = spp.buildEntry(page.args)
pageToEntryListMap[page.toString()] = newEntries
for (newEntry in newEntries) {
if (!entryMap.containsKey(newEntry.id)) {
entryQueue.push(newEntry)
entryMap.put(newEntry.id, newEntry)
}
}
}
}
fun printAllPages() {
for (entry in pageToEntryListMap.entries) {
logMsg("page: ${entry.key} with ${entry.value.size} entries")
}
}
fun printAllEntries() {
for (entry in entryMap.values) {
logMsg("entry: $entry")
}
}
}
private fun logMsg(message: String) {
Log.d("EntryRepo", message)
}

View File

@@ -28,8 +28,8 @@ interface SettingsPageProvider {
/** The page name without arguments. */
val name: String
/** The page arguments, default is no arguments. */
val arguments: List<NamedNavArgument>
/** The page parameters, default is no parameters. */
val parameter: List<NamedNavArgument>
get() = emptyList()
/** The [Composable] used to render this page. */

View File

@@ -18,22 +18,33 @@ package com.android.settingslib.spa.framework.common
class SettingsPageProviderRepository(
allPagesList: List<SettingsPageProvider>,
private val rootPages: List<String>
private val rootPages: List<String> = emptyList(),
// TODO: deprecate rootPages above
private val rootPageData: List<SettingsPage> = emptyList(),
) {
// Maintains all SPA page providers.
private val allPages: Map<String, SettingsPageProvider> = allPagesList.associateBy { it.name }
// Map of page name to its provider.
private val pageProviderMap: Map<String, SettingsPageProvider> =
allPagesList.associateBy { it.name }
fun getDefaultStartPageName(): String {
return rootPages.getOrElse(0) {
return ""
if (rootPageData.isNotEmpty()) {
return rootPageData[0].name
} else {
return rootPages.getOrElse(0) {
return ""
}
}
}
fun getAllRootPages(): Collection<SettingsPage> {
return rootPageData
}
fun getAllProviders(): Collection<SettingsPageProvider> {
return allPages.values
return pageProviderMap.values
}
fun getProviderOrNull(name: String): SettingsPageProvider? {
return allPages[name]
return pageProviderMap[name]
}
}

View File

@@ -0,0 +1,87 @@
/*
* Copyright (C) 2022 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.framework.util
import android.os.Bundle
import androidx.navigation.NamedNavArgument
import androidx.navigation.NavType
fun List<NamedNavArgument>.navRoute(): String {
return this.joinToString("") { argument -> "/{${argument.name}}" }
}
fun List<NamedNavArgument>.navLink(arguments: Bundle? = null): String {
if (arguments == null) return ""
val argsArray = mutableListOf<String>()
for (navArg in this) {
when (navArg.argument.type) {
NavType.StringType -> {
argsArray.add(arguments.getString(navArg.name, ""))
}
NavType.IntType -> {
argsArray.add(arguments.getInt(navArg.name).toString())
}
}
}
return argsArray.joinToString("") { arg -> "/$arg" }
}
fun List<NamedNavArgument>.normalize(arguments: Bundle? = null): Bundle {
if (arguments == null) return Bundle.EMPTY
val normArgs = Bundle()
for (navArg in this) {
when (navArg.argument.type) {
NavType.StringType -> {
val value = arguments.getString(navArg.name)
if (value != null) normArgs.putString(navArg.name, value)
}
NavType.IntType -> {
if (arguments.containsKey(navArg.name))
normArgs.putInt(navArg.name, arguments.getInt(navArg.name))
}
}
}
return normArgs
}
fun List<NamedNavArgument>.getStringArg(name: String, arguments: Bundle? = null): String? {
if (this.containsStringArg(name) && arguments != null) {
return arguments.getString(name)
}
return null
}
fun List<NamedNavArgument>.getIntArg(name: String, arguments: Bundle? = null): Int? {
if (this.containsIntArg(name) && arguments != null && arguments.containsKey(name)) {
return arguments.getInt(name)
}
return null
}
fun List<NamedNavArgument>.containsStringArg(name: String): Boolean {
for (navArg in this) {
if (navArg.argument.type == NavType.StringType && navArg.name == name) return true
}
return false
}
fun List<NamedNavArgument>.containsIntArg(name: String): Boolean {
for (navArg in this) {
if (navArg.argument.type == NavType.IntType && navArg.name == name) return true
}
return false
}

View File

@@ -47,7 +47,7 @@ internal class TogglePermissionAppInfoPageProvider(
) : SettingsPageProvider {
override val name = NAME
override val arguments = listOf(
override val parameter = listOf(
navArgument(PERMISSION) { type = NavType.StringType },
navArgument(PACKAGE_NAME) { type = NavType.StringType },
navArgument(USER_ID) { type = NavType.IntType },

View File

@@ -42,7 +42,7 @@ internal class TogglePermissionAppListPageProvider(
) : SettingsPageProvider {
override val name = NAME
override val arguments = listOf(
override val parameter = listOf(
navArgument(PERMISSION) { type = NavType.StringType },
)
@@ -81,6 +81,7 @@ internal class TogglePermissionAppListPageProvider(
* Expose route to enable enter from non-SPA pages.
*/
internal fun getRoute(permissionType: String) = "$NAME/$permissionType"
@Composable
internal fun navigator(permissionType: String) = navigator(route = getRoute(permissionType))
}