Refactor framework lib to better support debug activity & entry provider

in both gallery and SettingsGoogle.

Bug: 244122804
Test: manual - build Spa gallery
Change-Id: Iaf6083588f1c0234fa9ab7c493c7affa4561c516
This commit is contained in:
Zekan Qian
2022-09-21 13:16:35 +08:00
parent f9b4519081
commit 0b28238df2
5 changed files with 51 additions and 25 deletions

View File

@@ -20,6 +20,6 @@ import com.android.settingslib.spa.framework.DebugActivity
class GalleryDebugActivity : DebugActivity(
SpaEnvironment.EntryRepository,
MainActivity::class.java,
"com.android.spa.gallery.provider",
browseActivityClass = MainActivity::class.java,
entryProviderAuthorities = "com.android.spa.gallery.provider",
)

View File

@@ -20,5 +20,5 @@ import com.android.settingslib.spa.framework.EntryProvider
class GalleryEntryProvider : EntryProvider(
SpaEnvironment.EntryRepository,
"com.android.settingslib.spa.gallery/.MainActivity",
browseActivityClass = MainActivity::class.java,
)

View File

@@ -43,6 +43,7 @@ const val NULL_PAGE_NAME = "NULL"
* One can open any SPA page by:
* $ adb shell am start -n <BrowseActivityComponent> -e spa:SpaActivity:destination <SpaPageRoute>
* For gallery, BrowseActivityComponent = com.android.settingslib.spa.gallery/.MainActivity
* For SettingsGoogle, BrowseActivityComponent = com.android.settings/.spa.SpaActivity
* Some examples:
* $ adb shell am start -n <BrowseActivityComponent> -e spa:SpaActivity:destination HOME
* $ adb shell am start -n <BrowseActivityComponent> -e spa:SpaActivity:destination ARGUMENT/bar/5
@@ -104,7 +105,7 @@ open class BrowseActivity(
}
companion object {
const val KEY_DESTINATION = "spa:SpaActivity:destination"
const val KEY_DESTINATION = "spaActivityDestination"
const val HIGHLIGHT_ENTRY_PARAM_NAME = "highlightEntry"
}
}

View File

@@ -59,6 +59,7 @@ private const val PARAM_NAME_ENTRY_ID = "eid"
* One can open the debug activity by:
* $ adb shell am start -n <Activity>
* For gallery, Activity = com.android.settingslib.spa.gallery/.GalleryDebugActivity
* For SettingsGoogle, Activity = com.android.settings/.spa.SpaDebugActivity
*/
open class DebugActivity(
private val entryRepository: SettingsEntryRepository,
@@ -88,7 +89,7 @@ open class DebugActivity(
).use { cursor ->
while (cursor != null && cursor.moveToNext()) {
val route = cursor.getString(query, EntryProvider.ColumnEnum.PAGE_ROUTE)
val entryCount = cursor.getInt(query, EntryProvider.ColumnEnum.ENTRY_COUNT)
val entryCount = cursor.getInt(query, EntryProvider.ColumnEnum.PAGE_ENTRY_COUNT)
val hasRuntimeParam =
cursor.getBoolean(query, EntryProvider.ColumnEnum.HAS_RUNTIME_PARAM)
Log.d(
@@ -171,7 +172,7 @@ open class DebugActivity(
val id = arguments!!.getString(PARAM_NAME_PAGE_ID, "")
val pageWithEntry = entryRepository.getPageWithEntry(id)!!
RegularScaffold(title = "Page - ${pageWithEntry.page.displayName}") {
Text(text = pageWithEntry.page.id().toString())
Text(text = "id = ${pageWithEntry.page.id()}")
Text(text = pageWithEntry.page.formatArguments())
Text(text = "Entry size: ${pageWithEntry.entries.size}")
Preference(model = object : PreferenceModel {
@@ -213,8 +214,8 @@ open class DebugActivity(
@Composable
private fun openPage(page: SettingsPage): (() -> Unit)? {
if (page.hasRuntimeParam()) return null
val route = page.buildRoute()
val context = LocalContext.current
val route = page.buildRoute()
val intent = Intent(context, browseActivityClass).apply {
putExtra(KEY_DESTINATION, route)
}
@@ -227,8 +228,8 @@ open class DebugActivity(
@Composable
private fun openEntry(entry: SettingsEntry): (() -> Unit)? {
if (entry.hasRuntimeParam()) return null
val route = entry.buildRoute()
val context = LocalContext.current
val route = entry.buildRoute()
val intent = Intent(context, browseActivityClass).apply {
putExtra(KEY_DESTINATION, route)
}

View File

@@ -16,9 +16,12 @@
package com.android.settingslib.spa.framework
import android.content.ComponentName
import android.content.ContentProvider
import android.content.ContentValues
import android.content.Context
import android.content.Intent
import android.content.Intent.URI_INTENT_SCHEME
import android.content.UriMatcher
import android.content.pm.ProviderInfo
import android.database.Cursor
@@ -26,19 +29,21 @@ import android.database.MatrixCursor
import android.net.Uri
import android.util.Log
import com.android.settingslib.spa.framework.common.SettingsEntryRepository
import com.android.settingslib.spa.framework.common.SettingsPage
/**
* The content provider to return entry related data, which can be used for search and hierarchy.
* One can query the provider result by:
* $ adb shell content query --uri content://<AuthorityPath>/<QueryPath>
* For gallery, AuthorityPath = com.android.spa.gallery.provider
* For SettingsGoogle, AuthorityPath = com.android.settings.spa.provider
* Some examples:
* $ adb shell content query --uri content://<AuthorityPath>/page_start
* $ adb shell content query --uri content://<AuthorityPath>/page_info
*/
open class EntryProvider(
private val entryRepository: SettingsEntryRepository,
private val browseActivityComponentName: String? = null,
private val browseActivityClass: Class<*>? = null,
) : ContentProvider() {
/**
@@ -48,7 +53,8 @@ open class EntryProvider(
PAGE_ID("pageId"),
PAGE_NAME("pageName"),
PAGE_ROUTE("pageRoute"),
ENTRY_COUNT("entryCount"),
PAGE_INTENT_URI("pageIntent"),
PAGE_ENTRY_COUNT("entryCount"),
HAS_RUNTIME_PARAM("hasRuntimeParam"),
PAGE_START_ADB("pageStartAdb"),
}
@@ -71,13 +77,14 @@ open class EntryProvider(
ColumnEnum.PAGE_ID,
ColumnEnum.PAGE_NAME,
ColumnEnum.PAGE_ROUTE,
ColumnEnum.ENTRY_COUNT,
ColumnEnum.PAGE_INTENT_URI,
ColumnEnum.PAGE_ENTRY_COUNT,
ColumnEnum.HAS_RUNTIME_PARAM,
)
),
}
private var mMatcher: UriMatcher? = null
private var uriMatcher: UriMatcher? = null
override fun delete(uri: Uri, selection: String?, selectionArgs: Array<String>?): Int {
TODO("Implement this to handle requests to delete one or more rows")
@@ -108,14 +115,14 @@ open class EntryProvider(
}
override fun attachInfo(context: Context?, info: ProviderInfo?) {
mMatcher = UriMatcher(UriMatcher.NO_MATCH)
uriMatcher = UriMatcher(UriMatcher.NO_MATCH)
if (info != null) {
mMatcher!!.addURI(
uriMatcher!!.addURI(
info.authority,
QueryEnum.PAGE_START_COMMAND.queryPath,
QueryEnum.PAGE_START_COMMAND.queryMatchCode
)
mMatcher!!.addURI(
uriMatcher!!.addURI(
info.authority,
QueryEnum.PAGE_INFO_QUERY.queryPath,
QueryEnum.PAGE_INFO_QUERY.queryMatchCode
@@ -132,7 +139,7 @@ open class EntryProvider(
sortOrder: String?
): Cursor? {
return try {
when (mMatcher!!.match(uri)) {
when (uriMatcher!!.match(uri)) {
QueryEnum.PAGE_START_COMMAND.queryMatchCode -> queryPageStartCommand()
QueryEnum.PAGE_INFO_QUERY.queryMatchCode -> queryPageInfo()
else -> throw UnsupportedOperationException("Unknown Uri $uri")
@@ -146,16 +153,11 @@ open class EntryProvider(
}
private fun queryPageStartCommand(): Cursor {
val componentName = browseActivityComponentName ?: "<activity-component-name>"
val cursor = MatrixCursor(QueryEnum.PAGE_START_COMMAND.getColumns())
for (pageWithEntry in entryRepository.getAllPageWithEntry()) {
val page = pageWithEntry.page
if (!page.hasRuntimeParam()) {
cursor.newRow().add(
ColumnEnum.PAGE_START_ADB.id,
"adb shell am start -n $componentName" +
" -e ${BrowseActivity.KEY_DESTINATION} ${page.buildRoute()}"
)
val command = createBrowsePageAdbCommand(pageWithEntry.page)
if (command != null) {
cursor.newRow().add(ColumnEnum.PAGE_START_ADB.id, command)
}
}
return cursor
@@ -169,11 +171,33 @@ open class EntryProvider(
.add(ColumnEnum.PAGE_ID.id, page.id())
.add(ColumnEnum.PAGE_NAME.id, page.displayName)
.add(ColumnEnum.PAGE_ROUTE.id, page.buildRoute())
.add(ColumnEnum.ENTRY_COUNT.id, pageWithEntry.entries.size)
.add(ColumnEnum.PAGE_ENTRY_COUNT.id, pageWithEntry.entries.size)
.add(ColumnEnum.HAS_RUNTIME_PARAM.id, if (page.hasRuntimeParam()) 1 else 0)
.add(
ColumnEnum.PAGE_INTENT_URI.id,
createBrowsePageIntent(page).toUri(URI_INTENT_SCHEME)
)
}
return cursor
}
private fun createBrowsePageIntent(page: SettingsPage): Intent {
if (context == null || browseActivityClass == null || page.hasRuntimeParam())
return Intent()
return Intent().setComponent(ComponentName(context!!, browseActivityClass)).apply {
putExtra(BrowseActivity.KEY_DESTINATION, page.buildRoute())
}
}
private fun createBrowsePageAdbCommand(page: SettingsPage): String? {
if (context == null || page.hasRuntimeParam()) return null
val packageName = context!!.packageName
val activityName =
browseActivityClass?.name?.replace(packageName, "") ?: "<browse-activity-class>"
return "adb shell am start -n $packageName/$activityName" +
" -e ${BrowseActivity.KEY_DESTINATION} ${page.buildRoute()}"
}
}
fun EntryProvider.QueryEnum.getColumns(): Array<String> {