Merge "Support page open in DebugActivity"
This commit is contained in:
@@ -18,4 +18,4 @@ package com.android.settingslib.spa.gallery
|
||||
|
||||
import com.android.settingslib.spa.framework.DebugActivity
|
||||
|
||||
class GalleryDebugActivity : DebugActivity(SpaEnvironment.EntryRepository)
|
||||
class GalleryDebugActivity : DebugActivity(SpaEnvironment.EntryRepository, MainActivity::class.java)
|
||||
|
||||
@@ -68,7 +68,10 @@ object ArgumentPageProvider : SettingsPageProvider {
|
||||
private fun buildInjectEntry(arguments: Bundle?): SettingsEntryBuilder? {
|
||||
if (!ArgumentPageModel.isValidArgument(arguments)) return null
|
||||
|
||||
return SettingsEntryBuilder.createInject(SettingsPage.create(name, parameter, arguments))
|
||||
return SettingsEntryBuilder.createInject(
|
||||
entryName = ArgumentPageModel.getInjectEntryName(arguments),
|
||||
owner = SettingsPage.create(name, parameter, arguments)
|
||||
)
|
||||
// Set attributes
|
||||
.setIsAllowSearch(false)
|
||||
.setUiLayoutFn {
|
||||
|
||||
@@ -22,6 +22,7 @@ import androidx.compose.runtime.Composable
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import androidx.navigation.NavType
|
||||
import androidx.navigation.navArgument
|
||||
import com.android.settingslib.spa.framework.BrowseActivity
|
||||
import com.android.settingslib.spa.framework.common.PageModel
|
||||
import com.android.settingslib.spa.framework.compose.navigator
|
||||
import com.android.settingslib.spa.framework.compose.stateOf
|
||||
@@ -63,6 +64,10 @@ class ArgumentPageModel : PageModel() {
|
||||
return (stringParam != null && listOf("foo", "bar").contains(stringParam))
|
||||
}
|
||||
|
||||
fun getInjectEntryName(arguments: Bundle?): String {
|
||||
return "${name}_${parameter.getStringArg(STRING_PARAM_NAME, arguments)}"
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun create(arguments: Bundle?): ArgumentPageModel {
|
||||
val pageModel: ArgumentPageModel = viewModel(key = arguments.toString())
|
||||
@@ -75,12 +80,14 @@ class ArgumentPageModel : PageModel() {
|
||||
private var arguments: Bundle? = null
|
||||
private var stringParam: String? = null
|
||||
private var intParam: Int? = null
|
||||
private var highlightName: String? = null
|
||||
|
||||
override fun initialize(arguments: Bundle?) {
|
||||
logMsg("init with args " + arguments.toString())
|
||||
this.arguments = arguments
|
||||
stringParam = parameter.getStringArg(STRING_PARAM_NAME, arguments)
|
||||
intParam = parameter.getIntArg(INT_PARAM_NAME, arguments)
|
||||
highlightName = arguments?.getString(BrowseActivity.HIGHLIGHT_ENTRY_PARAM_NAME)
|
||||
}
|
||||
|
||||
@Composable
|
||||
|
||||
@@ -26,7 +26,9 @@ import androidx.navigation.NavGraph.Companion.findStartDestination
|
||||
import androidx.navigation.compose.NavHost
|
||||
import androidx.navigation.compose.composable
|
||||
import androidx.navigation.compose.rememberNavController
|
||||
import androidx.navigation.navArgument
|
||||
import com.android.settingslib.spa.R
|
||||
import com.android.settingslib.spa.framework.common.ROOT_PAGE_NAME
|
||||
import com.android.settingslib.spa.framework.common.SettingsPageProviderRepository
|
||||
import com.android.settingslib.spa.framework.compose.localNavController
|
||||
import com.android.settingslib.spa.framework.theme.SettingsTheme
|
||||
@@ -48,22 +50,28 @@ open class BrowseActivity(
|
||||
|
||||
@Composable
|
||||
private fun MainContent() {
|
||||
val destination = intent?.getStringExtra(KEY_DESTINATION)
|
||||
val destination =
|
||||
intent?.getStringExtra(KEY_DESTINATION) ?: sppRepository.getDefaultStartPageName()
|
||||
|
||||
val navController = rememberNavController()
|
||||
CompositionLocalProvider(navController.localNavController()) {
|
||||
NavHost(navController, sppRepository.getDefaultStartPageName()) {
|
||||
NavHost(navController, ROOT_PAGE_NAME) {
|
||||
composable(ROOT_PAGE_NAME) {}
|
||||
for (page in sppRepository.getAllProviders()) {
|
||||
composable(
|
||||
route = page.name + page.parameter.navRoute(),
|
||||
arguments = page.parameter,
|
||||
route = page.name + page.parameter.navRoute() +
|
||||
"?$HIGHLIGHT_ENTRY_PARAM_NAME={$HIGHLIGHT_ENTRY_PARAM_NAME}",
|
||||
arguments = page.parameter + listOf(
|
||||
// add optional parameters
|
||||
navArgument(HIGHLIGHT_ENTRY_PARAM_NAME) { defaultValue = "null" }
|
||||
),
|
||||
) { navBackStackEntry ->
|
||||
page.Page(navBackStackEntry.arguments)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!destination.isNullOrEmpty()) {
|
||||
if (destination.isNotEmpty()) {
|
||||
LaunchedEffect(Unit) {
|
||||
navController.navigate(destination) {
|
||||
popUpTo(navController.graph.findStartDestination().id) {
|
||||
@@ -77,5 +85,6 @@ open class BrowseActivity(
|
||||
|
||||
companion object {
|
||||
const val KEY_DESTINATION = "spa:SpaActivity:destination"
|
||||
const val HIGHLIGHT_ENTRY_PARAM_NAME = "highlightEntry"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,20 +16,25 @@
|
||||
|
||||
package com.android.settingslib.spa.framework
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.activity.compose.setContent
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.navigation.NavType
|
||||
import androidx.navigation.compose.NavHost
|
||||
import androidx.navigation.compose.composable
|
||||
import androidx.navigation.compose.rememberNavController
|
||||
import androidx.navigation.navArgument
|
||||
import com.android.settingslib.spa.R
|
||||
import com.android.settingslib.spa.framework.BrowseActivity.Companion.KEY_DESTINATION
|
||||
import com.android.settingslib.spa.framework.common.SettingsEntry
|
||||
import com.android.settingslib.spa.framework.common.SettingsEntryRepository
|
||||
import com.android.settingslib.spa.framework.common.SettingsPage
|
||||
import com.android.settingslib.spa.framework.compose.localNavController
|
||||
import com.android.settingslib.spa.framework.compose.navigator
|
||||
import com.android.settingslib.spa.framework.compose.toState
|
||||
@@ -48,7 +53,8 @@ private const val PARAM_NAME_PAGE_ID = "pid"
|
||||
private const val PARAM_NAME_ENTRY_ID = "eid"
|
||||
|
||||
open class DebugActivity(
|
||||
private val entryRepository: SettingsEntryRepository
|
||||
private val entryRepository: SettingsEntryRepository,
|
||||
private val browseActivityClass: Class<*>,
|
||||
) : ComponentActivity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
setTheme(R.style.Theme_SpaLib_DayNight)
|
||||
@@ -87,7 +93,7 @@ open class DebugActivity(
|
||||
|
||||
@Composable
|
||||
fun RootPage() {
|
||||
HomeScaffold(title = "Entry Debug") {
|
||||
HomeScaffold(title = "Settings Debug") {
|
||||
Preference(object : PreferenceModel {
|
||||
override val title = "List All Pages"
|
||||
override val onClick = navigator(route = ROUTE_All_PAGES)
|
||||
@@ -128,6 +134,10 @@ open class DebugActivity(
|
||||
RegularScaffold(title = "Page ${pageWithEntry.page.displayName}") {
|
||||
Text(text = pageWithEntry.page.formatArguments())
|
||||
Text(text = "Entry size: ${pageWithEntry.entries.size}")
|
||||
Preference(model = object : PreferenceModel {
|
||||
override val title = "open page"
|
||||
override val onClick = openPage(pageWithEntry.page)
|
||||
})
|
||||
EntryList(pageWithEntry.entries)
|
||||
}
|
||||
}
|
||||
@@ -137,7 +147,11 @@ open class DebugActivity(
|
||||
val id = arguments!!.getInt(PARAM_NAME_ENTRY_ID)
|
||||
val entry = entryRepository.getEntry(id)!!
|
||||
RegularScaffold(title = "Entry ${entry.displayName}") {
|
||||
Text (text = entry.formatAll())
|
||||
Preference(model = object : PreferenceModel {
|
||||
override val title = "open entry"
|
||||
override val onClick = openEntry(entry)
|
||||
})
|
||||
Text(text = entry.formatAll())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,4 +166,30 @@ open class DebugActivity(
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun openPage(page: SettingsPage): () -> Unit {
|
||||
val route = page.buildRoute()
|
||||
val context = LocalContext.current
|
||||
val intent = Intent(context, browseActivityClass).apply {
|
||||
putExtra(KEY_DESTINATION, route)
|
||||
}
|
||||
return {
|
||||
Log.d("DEBUG ACTIVITY", "Open page: $route")
|
||||
context.startActivity(intent)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun openEntry(entry: SettingsEntry): () -> Unit {
|
||||
val route = entry.buildRoute()
|
||||
val context = LocalContext.current
|
||||
val intent = Intent(context, browseActivityClass).apply {
|
||||
putExtra(KEY_DESTINATION, route)
|
||||
}
|
||||
return {
|
||||
Log.d("DEBUG ACTIVITY", "Open entry: $route")
|
||||
context.startActivity(intent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,10 +19,13 @@ package com.android.settingslib.spa.framework.common
|
||||
import android.os.Bundle
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.navigation.NamedNavArgument
|
||||
import com.android.settingslib.spa.framework.BrowseActivity
|
||||
import com.android.settingslib.spa.framework.util.navLink
|
||||
import com.android.settingslib.spa.framework.util.normalize
|
||||
|
||||
const val INJECT_ENTRY_NAME = "INJECT"
|
||||
const val ROOT_ENTRY_NAME = "ROOT"
|
||||
const val ROOT_PAGE_NAME = "Root"
|
||||
|
||||
/**
|
||||
* Defines data of one Settings entry for Settings search.
|
||||
@@ -38,7 +41,7 @@ data class UiData(val title: String = "")
|
||||
* Defines data to identify a Settings page.
|
||||
*/
|
||||
data class SettingsPage(
|
||||
// The unique id of this page, which is computed by name + arguments
|
||||
// The unique id of this page, which is computed by name + normalized(arguments)
|
||||
val id: Int,
|
||||
|
||||
// The name of the page, which is used to compute the unique id, and need to be stable.
|
||||
@@ -48,6 +51,9 @@ data class SettingsPage(
|
||||
// By default, it is the same as name.
|
||||
val displayName: String,
|
||||
|
||||
// Defined parameters of this page.
|
||||
val parameter: List<NamedNavArgument> = emptyList(),
|
||||
|
||||
// The arguments of this page.
|
||||
val arguments: Bundle? = null,
|
||||
) {
|
||||
@@ -62,13 +68,23 @@ data class SettingsPage(
|
||||
}
|
||||
|
||||
fun formatArguments(): String {
|
||||
if (arguments == null || arguments.isEmpty) return "[No arguments]"
|
||||
return arguments.toString().removeRange(0, 6)
|
||||
val normalizedArguments = parameter.normalize(arguments)
|
||||
if (normalizedArguments == null || normalizedArguments.isEmpty) return "[No arguments]"
|
||||
return normalizedArguments.toString().removeRange(0, 6)
|
||||
}
|
||||
|
||||
fun formatAll(): String {
|
||||
return "$displayName ${formatArguments()}"
|
||||
}
|
||||
|
||||
fun buildRoute(highlightEntryName: String? = null): String {
|
||||
val highlightParam =
|
||||
if (highlightEntryName == null)
|
||||
""
|
||||
else
|
||||
"?${BrowseActivity.HIGHLIGHT_ENTRY_PARAM_NAME}=$highlightEntryName"
|
||||
return name + parameter.navLink(arguments) + highlightParam
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -133,6 +149,12 @@ data class SettingsEntry(
|
||||
)
|
||||
return content.joinToString("\n")
|
||||
}
|
||||
|
||||
fun buildRoute(): String {
|
||||
// Open entry in its fromPage.
|
||||
val page = fromPage ?: owner
|
||||
return page.buildRoute(name)
|
||||
}
|
||||
}
|
||||
|
||||
data class SettingsPageWithEntry(
|
||||
@@ -153,7 +175,8 @@ class SettingsPageBuilder(
|
||||
id = "$name:${normArguments?.toString()}".toUniqueId(),
|
||||
name = name,
|
||||
displayName = displayName ?: name,
|
||||
arguments = normArguments,
|
||||
parameter = parameter,
|
||||
arguments = arguments,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -234,12 +257,14 @@ class SettingsEntryBuilder(private val name: String, private val owner: Settings
|
||||
return create(entryName, owner).setLink(toPage = owner)
|
||||
}
|
||||
|
||||
fun createInject(owner: SettingsPage): SettingsEntryBuilder {
|
||||
return createLinkTo(INJECT_ENTRY_NAME, owner)
|
||||
fun createInject(owner: SettingsPage, entryName: String? = null): SettingsEntryBuilder {
|
||||
val name = entryName ?: "${INJECT_ENTRY_NAME}_${owner.name}"
|
||||
return createLinkTo(name, owner)
|
||||
}
|
||||
|
||||
fun createRoot(page: SettingsPage): SettingsEntryBuilder {
|
||||
return createLinkTo(ROOT_ENTRY_NAME, page)
|
||||
fun createRoot(owner: SettingsPage, entryName: String? = null): SettingsEntryBuilder {
|
||||
val name = entryName ?: "${ROOT_ENTRY_NAME}_${owner.name}"
|
||||
return createLinkTo(name, owner)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ class SettingsEntryRepository(sppRepository: SettingsPageProviderRepository) {
|
||||
|
||||
val entryQueue = LinkedList<SettingsEntry>()
|
||||
for (page in sppRepository.getAllRootPages()) {
|
||||
val rootEntry = SettingsEntryBuilder.createRoot(page).build()
|
||||
val rootEntry = SettingsEntryBuilder.createRoot(owner = page).build()
|
||||
if (!entryMap.containsKey(rootEntry.id)) {
|
||||
entryQueue.push(rootEntry)
|
||||
entryMap.put(rootEntry.id, rootEntry)
|
||||
|
||||
@@ -110,7 +110,7 @@ internal class TogglePermissionAppListPageProvider(
|
||||
internal fun buildInjectEntry(permissionType: String): SettingsEntryBuilder {
|
||||
val appListPage = SettingsPage.create(
|
||||
PAGE_NAME, PAGE_PARAMETER, bundleOf(PERMISSION to permissionType))
|
||||
return SettingsEntryBuilder.createInject(appListPage).setIsAllowSearch(false)
|
||||
return SettingsEntryBuilder.createInject(owner = appListPage).setIsAllowSearch(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user