Add getStatusData API in entry.
Use this API to fetch status of entry, such as isDisabled / isSwitchOff Add query_status in EntryProvider Bug: 253981143 Test: manual - build gallery Change-Id: I5ee3dfae59199c3efd169d163cbee5f39b3c451a
This commit is contained in:
@@ -27,6 +27,7 @@ import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import com.android.settingslib.spa.framework.common.EntrySearchData
|
||||
import com.android.settingslib.spa.framework.common.EntryStatusData
|
||||
import com.android.settingslib.spa.framework.common.SettingsEntry
|
||||
import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
|
||||
import com.android.settingslib.spa.framework.common.SettingsPageProvider
|
||||
@@ -104,6 +105,7 @@ object PreferencePageProvider : SettingsPageProvider {
|
||||
entryList.add(
|
||||
createEntry(EntryEnum.DISABLED_PREFERENCE)
|
||||
.setIsAllowSearch(true)
|
||||
.setHasMutableStatus(true)
|
||||
.setMacro {
|
||||
spaLogger.message(TAG, "create macro for ${EntryEnum.DISABLED_PREFERENCE}")
|
||||
SimplePreferenceMacro(
|
||||
@@ -113,14 +115,17 @@ object PreferencePageProvider : SettingsPageProvider {
|
||||
icon = Icons.Outlined.DisabledByDefault,
|
||||
)
|
||||
}
|
||||
.setStatusDataFn { EntryStatusData(isDisabled = true) }
|
||||
.build()
|
||||
)
|
||||
entryList.add(
|
||||
createEntry(EntryEnum.ASYNC_SUMMARY_PREFERENCE)
|
||||
.setIsAllowSearch(true)
|
||||
.setHasMutableStatus(true)
|
||||
.setSearchDataFn {
|
||||
EntrySearchData(title = ASYNC_PREFERENCE_TITLE)
|
||||
}
|
||||
.setStatusDataFn { EntryStatusData(isDisabled = false) }
|
||||
.setUiLayoutFn {
|
||||
val model = PreferencePageModel.create()
|
||||
val asyncSummary = remember { model.getAsyncSummary() }
|
||||
|
||||
@@ -42,9 +42,10 @@ private const val TAG = "EntryProvider"
|
||||
* For gallery, AuthorityPath = com.android.spa.gallery.provider
|
||||
* For Settings, AuthorityPath = com.android.settings.spa.provider
|
||||
* Some examples:
|
||||
* $ adb shell content query --uri content://<AuthorityPath>/search_sitemap
|
||||
* $ adb shell content query --uri content://<AuthorityPath>/search_static
|
||||
* $ adb shell content query --uri content://<AuthorityPath>/search_dynamic
|
||||
* $ adb shell content query --uri content://<AuthorityPath>/search_mutable_status
|
||||
* $ adb shell content query --uri content://<AuthorityPath>/search_immutable_status
|
||||
*/
|
||||
open class EntryProvider : ContentProvider() {
|
||||
private val spaEnvironment get() = SpaEnvironmentFactory.instance
|
||||
@@ -81,9 +82,10 @@ open class EntryProvider : ContentProvider() {
|
||||
|
||||
override fun attachInfo(context: Context?, info: ProviderInfo?) {
|
||||
if (info != null) {
|
||||
QueryEnum.SEARCH_SITEMAP_QUERY.addUri(uriMatcher, info.authority)
|
||||
QueryEnum.SEARCH_STATIC_DATA_QUERY.addUri(uriMatcher, info.authority)
|
||||
QueryEnum.SEARCH_DYNAMIC_DATA_QUERY.addUri(uriMatcher, info.authority)
|
||||
QueryEnum.SEARCH_MUTABLE_STATUS_DATA_QUERY.addUri(uriMatcher, info.authority)
|
||||
QueryEnum.SEARCH_IMMUTABLE_STATUS_DATA_QUERY.addUri(uriMatcher, info.authority)
|
||||
}
|
||||
super.attachInfo(context, info)
|
||||
}
|
||||
@@ -97,9 +99,12 @@ open class EntryProvider : ContentProvider() {
|
||||
): Cursor? {
|
||||
return try {
|
||||
when (uriMatcher.match(uri)) {
|
||||
QueryEnum.SEARCH_SITEMAP_QUERY.queryMatchCode -> querySearchSitemap()
|
||||
QueryEnum.SEARCH_STATIC_DATA_QUERY.queryMatchCode -> querySearchStaticData()
|
||||
QueryEnum.SEARCH_DYNAMIC_DATA_QUERY.queryMatchCode -> querySearchDynamicData()
|
||||
QueryEnum.SEARCH_MUTABLE_STATUS_DATA_QUERY.queryMatchCode ->
|
||||
querySearchMutableStatusData()
|
||||
QueryEnum.SEARCH_IMMUTABLE_STATUS_DATA_QUERY.queryMatchCode ->
|
||||
querySearchImmutableStatusData()
|
||||
else -> throw UnsupportedOperationException("Unknown Uri $uri")
|
||||
}
|
||||
} catch (e: UnsupportedOperationException) {
|
||||
@@ -110,18 +115,22 @@ open class EntryProvider : ContentProvider() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun querySearchSitemap(): Cursor {
|
||||
private fun querySearchImmutableStatusData(): Cursor {
|
||||
val entryRepository by spaEnvironment.entryRepository
|
||||
val cursor = MatrixCursor(QueryEnum.SEARCH_SITEMAP_QUERY.getColumns())
|
||||
val cursor = MatrixCursor(QueryEnum.SEARCH_IMMUTABLE_STATUS_DATA_QUERY.getColumns())
|
||||
for (entry in entryRepository.getAllEntries()) {
|
||||
if (!entry.isAllowSearch) continue
|
||||
val intent = entry.containerPage()
|
||||
.createBrowseIntent(context, spaEnvironment.browseActivityClass, entry.id)
|
||||
?: Intent()
|
||||
cursor.newRow()
|
||||
.add(ColumnEnum.ENTRY_ID.id, entry.id)
|
||||
.add(ColumnEnum.ENTRY_HIERARCHY_PATH.id, entryRepository.getEntryPath(entry.id))
|
||||
.add(ColumnEnum.ENTRY_INTENT_URI.id, intent.toUri(Intent.URI_INTENT_SCHEME))
|
||||
if (!entry.isAllowSearch || entry.mutableStatus) continue
|
||||
fetchStatusData(entry, cursor)
|
||||
}
|
||||
return cursor
|
||||
}
|
||||
|
||||
private fun querySearchMutableStatusData(): Cursor {
|
||||
val entryRepository by spaEnvironment.entryRepository
|
||||
val cursor = MatrixCursor(QueryEnum.SEARCH_MUTABLE_STATUS_DATA_QUERY.getColumns())
|
||||
for (entry in entryRepository.getAllEntries()) {
|
||||
if (!entry.isAllowSearch || !entry.mutableStatus) continue
|
||||
fetchStatusData(entry, cursor)
|
||||
}
|
||||
return cursor
|
||||
}
|
||||
@@ -147,14 +156,27 @@ open class EntryProvider : ContentProvider() {
|
||||
}
|
||||
|
||||
private fun fetchSearchData(entry: SettingsEntry, cursor: MatrixCursor) {
|
||||
val entryRepository by spaEnvironment.entryRepository
|
||||
val browseActivityClass = spaEnvironment.browseActivityClass
|
||||
|
||||
// Fetch search data. We can add runtime arguments later if necessary
|
||||
val searchData = entry.getSearchData()
|
||||
val searchData = entry.getSearchData() ?: return
|
||||
val intent = entry.containerPage()
|
||||
.createBrowseIntent(context, browseActivityClass, entry.id)
|
||||
?: Intent()
|
||||
cursor.newRow()
|
||||
.add(ColumnEnum.ENTRY_ID.id, entry.id)
|
||||
.add(ColumnEnum.ENTRY_TITLE.id, searchData?.title ?: "")
|
||||
.add(
|
||||
ColumnEnum.ENTRY_SEARCH_KEYWORD.id,
|
||||
searchData?.keyword ?: emptyList<String>()
|
||||
)
|
||||
.add(ColumnEnum.ENTRY_INTENT_URI.id, intent.toUri(Intent.URI_INTENT_SCHEME))
|
||||
.add(ColumnEnum.SEARCH_TITLE.id, searchData.title)
|
||||
.add(ColumnEnum.SEARCH_KEYWORD.id, searchData.keyword)
|
||||
.add(ColumnEnum.SEARCH_PATH.id, entryRepository.getEntryPath(entry.id))
|
||||
}
|
||||
|
||||
private fun fetchStatusData(entry: SettingsEntry, cursor: MatrixCursor) {
|
||||
// Fetch status data. We can add runtime arguments later if necessary
|
||||
val statusData = entry.getStatusData() ?: return
|
||||
cursor.newRow()
|
||||
.add(ColumnEnum.ENTRY_ID.id, entry.id)
|
||||
.add(ColumnEnum.SEARCH_STATUS_DISABLED.id, statusData.isDisabled)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,4 +26,5 @@ interface EntryMacro {
|
||||
@Composable
|
||||
fun UiLayout() {}
|
||||
fun getSearchData(): EntrySearchData? = null
|
||||
fun getStatusData(): EntryStatusData? = null
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
/**
|
||||
* Defines the status data of one Settings entry, which could be changed frequently.
|
||||
*/
|
||||
data class EntryStatusData(
|
||||
val isDisabled: Boolean = false,
|
||||
val isSwitchOff: Boolean = false,
|
||||
)
|
||||
@@ -40,8 +40,10 @@ enum class ColumnEnum(val id: String) {
|
||||
ENTRY_START_ADB("entryStartAdb"),
|
||||
|
||||
// Columns related to search
|
||||
ENTRY_TITLE("entryTitle"),
|
||||
ENTRY_SEARCH_KEYWORD("entrySearchKw"),
|
||||
SEARCH_TITLE("searchTitle"),
|
||||
SEARCH_KEYWORD("searchKw"),
|
||||
SEARCH_PATH("searchPath"),
|
||||
SEARCH_STATUS_DISABLED("searchDisabled"),
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -83,32 +85,42 @@ enum class QueryEnum(
|
||||
ColumnEnum.ENTRY_NAME,
|
||||
ColumnEnum.ENTRY_ROUTE,
|
||||
ColumnEnum.ENTRY_INTENT_URI,
|
||||
ColumnEnum.ENTRY_HIERARCHY_PATH,
|
||||
)
|
||||
),
|
||||
|
||||
// Search related queries
|
||||
SEARCH_SITEMAP_QUERY(
|
||||
"search_sitemap", 300,
|
||||
listOf(
|
||||
ColumnEnum.ENTRY_ID,
|
||||
ColumnEnum.ENTRY_HIERARCHY_PATH,
|
||||
ColumnEnum.ENTRY_INTENT_URI,
|
||||
)
|
||||
),
|
||||
SEARCH_STATIC_DATA_QUERY(
|
||||
"search_static", 301,
|
||||
listOf(
|
||||
ColumnEnum.ENTRY_ID,
|
||||
ColumnEnum.ENTRY_TITLE,
|
||||
ColumnEnum.ENTRY_SEARCH_KEYWORD,
|
||||
ColumnEnum.ENTRY_INTENT_URI,
|
||||
ColumnEnum.SEARCH_TITLE,
|
||||
ColumnEnum.SEARCH_KEYWORD,
|
||||
ColumnEnum.SEARCH_PATH,
|
||||
)
|
||||
),
|
||||
SEARCH_DYNAMIC_DATA_QUERY(
|
||||
"search_dynamic", 302,
|
||||
listOf(
|
||||
ColumnEnum.ENTRY_ID,
|
||||
ColumnEnum.ENTRY_TITLE,
|
||||
ColumnEnum.ENTRY_SEARCH_KEYWORD,
|
||||
ColumnEnum.ENTRY_INTENT_URI,
|
||||
ColumnEnum.SEARCH_TITLE,
|
||||
ColumnEnum.SEARCH_KEYWORD,
|
||||
ColumnEnum.SEARCH_PATH,
|
||||
)
|
||||
),
|
||||
SEARCH_IMMUTABLE_STATUS_DATA_QUERY(
|
||||
"search_immutable_status", 303,
|
||||
listOf(
|
||||
ColumnEnum.ENTRY_ID,
|
||||
ColumnEnum.SEARCH_STATUS_DISABLED,
|
||||
)
|
||||
),
|
||||
SEARCH_MUTABLE_STATUS_DATA_QUERY(
|
||||
"search_mutable_status", 304,
|
||||
listOf(
|
||||
ColumnEnum.ENTRY_ID,
|
||||
ColumnEnum.SEARCH_STATUS_DISABLED,
|
||||
)
|
||||
),
|
||||
}
|
||||
|
||||
@@ -65,8 +65,14 @@ data class SettingsEntry(
|
||||
* ========================================
|
||||
*/
|
||||
val isAllowSearch: Boolean = false,
|
||||
|
||||
// Indicate whether the search indexing data of entry is dynamic.
|
||||
val isSearchDataDynamic: Boolean = false,
|
||||
|
||||
// Indicate whether the status of entry is mutable.
|
||||
// If so, for instance, we'll reindex its status for search.
|
||||
val mutableStatus: Boolean = false,
|
||||
|
||||
/**
|
||||
* ========================================
|
||||
* Defines entry APIs to get data here.
|
||||
@@ -74,8 +80,14 @@ data class SettingsEntry(
|
||||
*/
|
||||
|
||||
/**
|
||||
* API to get Search related data for this entry.
|
||||
* Returns null if this entry is not available for the search at the moment.
|
||||
* API to get the status data of the entry, such as isDisabled / isSwitchOff.
|
||||
* Returns null if this entry do NOT have any status.
|
||||
*/
|
||||
private val statusDataImpl: (arguments: Bundle?) -> EntryStatusData? = { null },
|
||||
|
||||
/**
|
||||
* API to get Search indexing data for this entry, such as title / keyword.
|
||||
* Returns null if this entry do NOT support search.
|
||||
*/
|
||||
private val searchDataImpl: (arguments: Bundle?) -> EntrySearchData? = { null },
|
||||
|
||||
@@ -116,6 +128,10 @@ data class SettingsEntry(
|
||||
return arguments
|
||||
}
|
||||
|
||||
fun getStatusData(runtimeArguments: Bundle? = null): EntryStatusData? {
|
||||
return statusDataImpl(fullArgument(runtimeArguments))
|
||||
}
|
||||
|
||||
fun getSearchData(runtimeArguments: Bundle? = null): EntrySearchData? {
|
||||
return searchDataImpl(fullArgument(runtimeArguments))
|
||||
}
|
||||
@@ -151,8 +167,10 @@ class SettingsEntryBuilder(private val name: String, private val owner: Settings
|
||||
// Attributes
|
||||
private var isAllowSearch: Boolean = false
|
||||
private var isSearchDataDynamic: Boolean = false
|
||||
private var mutableStatus: Boolean = false
|
||||
|
||||
// Functions
|
||||
private var statusDataFn: (arguments: Bundle?) -> EntryStatusData? = { null }
|
||||
private var searchDataFn: (arguments: Bundle?) -> EntrySearchData? = { null }
|
||||
private var uiLayoutFn: (@Composable (arguments: Bundle?) -> Unit) = { }
|
||||
|
||||
@@ -170,8 +188,10 @@ class SettingsEntryBuilder(private val name: String, private val owner: Settings
|
||||
// attributes
|
||||
isAllowSearch = isAllowSearch,
|
||||
isSearchDataDynamic = isSearchDataDynamic,
|
||||
mutableStatus = mutableStatus,
|
||||
|
||||
// functions
|
||||
statusDataImpl = statusDataFn,
|
||||
searchDataImpl = searchDataFn,
|
||||
uiLayoutImpl = uiLayoutFn,
|
||||
)
|
||||
@@ -201,7 +221,13 @@ class SettingsEntryBuilder(private val name: String, private val owner: Settings
|
||||
return this
|
||||
}
|
||||
|
||||
fun setHasMutableStatus(hasMutableStatus: Boolean): SettingsEntryBuilder {
|
||||
this.mutableStatus = hasMutableStatus
|
||||
return this
|
||||
}
|
||||
|
||||
fun setMacro(fn: (arguments: Bundle?) -> EntryMacro): SettingsEntryBuilder {
|
||||
setStatusDataFn { fn(it).getStatusData() }
|
||||
setSearchDataFn { fn(it).getSearchData() }
|
||||
setUiLayoutFn {
|
||||
val macro = remember { fn(it) }
|
||||
@@ -210,6 +236,11 @@ class SettingsEntryBuilder(private val name: String, private val owner: Settings
|
||||
return this
|
||||
}
|
||||
|
||||
fun setStatusDataFn(fn: (arguments: Bundle?) -> EntryStatusData?): SettingsEntryBuilder {
|
||||
this.statusDataFn = fn
|
||||
return this
|
||||
}
|
||||
|
||||
fun setSearchDataFn(fn: (arguments: Bundle?) -> EntrySearchData?): SettingsEntryBuilder {
|
||||
this.searchDataFn = fn
|
||||
return this
|
||||
|
||||
@@ -170,6 +170,7 @@ class DebugProvider : ContentProvider() {
|
||||
.add(ColumnEnum.ENTRY_NAME.id, entry.displayName)
|
||||
.add(ColumnEnum.ENTRY_ROUTE.id, entry.containerPage().buildRoute())
|
||||
.add(ColumnEnum.ENTRY_INTENT_URI.id, intent.toUri(URI_INTENT_SCHEME))
|
||||
.add(ColumnEnum.ENTRY_HIERARCHY_PATH.id, entryRepository.getEntryPath(entry.id))
|
||||
}
|
||||
return cursor
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import com.android.settingslib.spa.framework.common.EntryMacro
|
||||
import com.android.settingslib.spa.framework.common.EntrySearchData
|
||||
import com.android.settingslib.spa.framework.common.EntryStatusData
|
||||
import com.android.settingslib.spa.framework.compose.navigator
|
||||
import com.android.settingslib.spa.framework.compose.stateOf
|
||||
import com.android.settingslib.spa.framework.util.wrapOnClickWithLog
|
||||
@@ -55,6 +56,10 @@ data class SimplePreferenceMacro(
|
||||
keyword = searchKeywords
|
||||
)
|
||||
}
|
||||
|
||||
override fun getStatusData(): EntryStatusData {
|
||||
return EntryStatusData(isDisabled = false)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user