diff options
| author | 2022-10-19 15:24:15 +0800 | |
|---|---|---|
| committer | 2022-10-19 16:27:03 +0800 | |
| commit | 285690dcc31b7fdbbb8b4012a4f8cd21ee63e91c (patch) | |
| tree | fa00f244d473a7686f801de02e307b901fcbe46a | |
| parent | 9c246c8d7566b6d4eea4c6bc94c1068f6c9cadd1 (diff) | |
Move debug related activity & provider to debug folder.
Add debug related activity & provider in Gallery.
Bug: 244122804
Test: manual - build gallery
Change-Id: Ie1b005b26eca5b7dd6472ebf6841531c2bc7a071
| -rw-r--r-- | packages/SettingsLib/Spa/gallery/AndroidManifest.xml | 18 | ||||
| -rw-r--r-- | packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/GalleryDebugActivity.kt | 21 | ||||
| -rw-r--r-- | packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/EntryProvider.kt | 238 | ||||
| -rw-r--r-- | packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/ProviderColumn.kt | 126 | ||||
| -rw-r--r-- | packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsPage.kt | 40 | ||||
| -rw-r--r-- | packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/debug/DebugActivity.kt (renamed from packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/DebugActivity.kt) | 85 | ||||
| -rw-r--r-- | packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/debug/DebugProvider.kt | 176 |
7 files changed, 390 insertions, 314 deletions
diff --git a/packages/SettingsLib/Spa/gallery/AndroidManifest.xml b/packages/SettingsLib/Spa/gallery/AndroidManifest.xml index 2ed8bca1e5d8..f1a24aff4319 100644 --- a/packages/SettingsLib/Spa/gallery/AndroidManifest.xml +++ b/packages/SettingsLib/Spa/gallery/AndroidManifest.xml @@ -34,14 +34,24 @@ </intent-filter> </activity> + <provider + android:name=".GalleryEntryProvider" + android:authorities="com.android.spa.gallery.provider" + android:enabled="true" + android:exported="false"> + </provider> + <activity - android:name=".GalleryDebugActivity" + android:name="com.android.settingslib.spa.framework.debug.BlankActivity" + android:exported="true"> + </activity> + <activity + android:name="com.android.settingslib.spa.framework.debug.DebugActivity" android:exported="true"> </activity> - <provider - android:name=".GalleryEntryProvider" - android:authorities="com.android.spa.gallery.provider" + android:name="com.android.settingslib.spa.framework.debug.DebugProvider" + android:authorities="com.android.spa.gallery.debug" android:enabled="true" android:exported="false"> </provider> diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/GalleryDebugActivity.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/GalleryDebugActivity.kt deleted file mode 100644 index 23072a231417..000000000000 --- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/GalleryDebugActivity.kt +++ /dev/null @@ -1,21 +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.gallery - -import com.android.settingslib.spa.framework.DebugActivity - -class GalleryDebugActivity : DebugActivity() diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/EntryProvider.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/EntryProvider.kt index 532f63b67c5d..d6317085e4f9 100644 --- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/EntryProvider.kt +++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/EntryProvider.kt @@ -16,21 +16,22 @@ 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 import android.database.MatrixCursor import android.net.Uri import android.util.Log +import com.android.settingslib.spa.framework.common.ColumnEnum +import com.android.settingslib.spa.framework.common.QueryEnum import com.android.settingslib.spa.framework.common.SettingsEntry -import com.android.settingslib.spa.framework.common.SettingsPage import com.android.settingslib.spa.framework.common.SpaEnvironmentFactory +import com.android.settingslib.spa.framework.common.addUri +import com.android.settingslib.spa.framework.common.getColumns private const val TAG = "EntryProvider" @@ -39,117 +40,15 @@ private const val TAG = "EntryProvider" * 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 + * For Settings, AuthorityPath = com.android.settings.spa.provider * Some examples: - * $ adb shell content query --uri content://<AuthorityPath>/page_debug - * $ adb shell content query --uri content://<AuthorityPath>/entry_debug - * $ adb shell content query --uri content://<AuthorityPath>/page_info - * $ adb shell content query --uri content://<AuthorityPath>/entry_info * $ 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 */ open class EntryProvider : ContentProvider() { private val spaEnvironment get() = SpaEnvironmentFactory.instance - - /** - * Enum to define all column names in provider. - */ - enum class ColumnEnum(val id: String) { - // Columns related to page - PAGE_ID("pageId"), - PAGE_NAME("pageName"), - PAGE_ROUTE("pageRoute"), - PAGE_INTENT_URI("pageIntent"), - PAGE_ENTRY_COUNT("entryCount"), - HAS_RUNTIME_PARAM("hasRuntimeParam"), - PAGE_START_ADB("pageStartAdb"), - - // Columns related to entry - ENTRY_ID("entryId"), - ENTRY_NAME("entryName"), - ENTRY_ROUTE("entryRoute"), - ENTRY_INTENT_URI("entryIntent"), - ENTRY_HIERARCHY_PATH("entryPath"), - ENTRY_START_ADB("entryStartAdb"), - - // Columns related to search - ENTRY_TITLE("entryTitle"), - ENTRY_SEARCH_KEYWORD("entrySearchKw"), - } - - /** - * Enum to define all queries supported in the provider. - */ - enum class QueryEnum( - val queryPath: String, - val queryMatchCode: Int, - val columnNames: List<ColumnEnum> - ) { - // For debug - PAGE_DEBUG_QUERY( - "page_debug", 1, - listOf(ColumnEnum.PAGE_START_ADB) - ), - ENTRY_DEBUG_QUERY( - "entry_debug", 2, - listOf(ColumnEnum.ENTRY_START_ADB) - ), - - // page related queries. - PAGE_INFO_QUERY( - "page_info", 100, - listOf( - ColumnEnum.PAGE_ID, - ColumnEnum.PAGE_NAME, - ColumnEnum.PAGE_ROUTE, - ColumnEnum.PAGE_INTENT_URI, - ColumnEnum.PAGE_ENTRY_COUNT, - ColumnEnum.HAS_RUNTIME_PARAM, - ) - ), - - // entry related queries - ENTRY_INFO_QUERY( - "entry_info", 200, - listOf( - ColumnEnum.ENTRY_ID, - ColumnEnum.ENTRY_NAME, - ColumnEnum.ENTRY_ROUTE, - ColumnEnum.ENTRY_INTENT_URI, - ) - ), - - // Search related queries - SEARCH_SITEMAP_QUERY( - "search_sitemap", 300, - listOf( - ColumnEnum.ENTRY_ID, - ColumnEnum.ENTRY_HIERARCHY_PATH, - ) - ), - SEARCH_STATIC_DATA_QUERY( - "search_static", 301, - listOf( - ColumnEnum.ENTRY_ID, - ColumnEnum.ENTRY_TITLE, - ColumnEnum.ENTRY_SEARCH_KEYWORD, - ) - ), - SEARCH_DYNAMIC_DATA_QUERY( - "search_dynamic", 302, - listOf( - ColumnEnum.ENTRY_ID, - ColumnEnum.ENTRY_TITLE, - ColumnEnum.ENTRY_SEARCH_KEYWORD, - ) - ), - } - private val uriMatcher = UriMatcher(UriMatcher.NO_MATCH) - private fun addUri(authority: String, query: QueryEnum) { - uriMatcher.addURI(authority, query.queryPath, query.queryMatchCode) - } override fun delete(uri: Uri, selection: String?, selectionArgs: Array<String>?): Int { TODO("Implement this to handle requests to delete one or more rows") @@ -182,13 +81,9 @@ open class EntryProvider : ContentProvider() { override fun attachInfo(context: Context?, info: ProviderInfo?) { if (info != null) { - addUri(info.authority, QueryEnum.PAGE_DEBUG_QUERY) - addUri(info.authority, QueryEnum.ENTRY_DEBUG_QUERY) - addUri(info.authority, QueryEnum.PAGE_INFO_QUERY) - addUri(info.authority, QueryEnum.ENTRY_INFO_QUERY) - addUri(info.authority, QueryEnum.SEARCH_SITEMAP_QUERY) - addUri(info.authority, QueryEnum.SEARCH_STATIC_DATA_QUERY) - addUri(info.authority, QueryEnum.SEARCH_DYNAMIC_DATA_QUERY) + 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) } super.attachInfo(context, info) } @@ -202,10 +97,6 @@ open class EntryProvider : ContentProvider() { ): Cursor? { return try { when (uriMatcher.match(uri)) { - QueryEnum.PAGE_DEBUG_QUERY.queryMatchCode -> queryPageDebug() - QueryEnum.ENTRY_DEBUG_QUERY.queryMatchCode -> queryEntryDebug() - QueryEnum.PAGE_INFO_QUERY.queryMatchCode -> queryPageInfo() - QueryEnum.ENTRY_INFO_QUERY.queryMatchCode -> queryEntryInfo() QueryEnum.SEARCH_SITEMAP_QUERY.queryMatchCode -> querySearchSitemap() QueryEnum.SEARCH_STATIC_DATA_QUERY.queryMatchCode -> querySearchStaticData() QueryEnum.SEARCH_DYNAMIC_DATA_QUERY.queryMatchCode -> querySearchDynamicData() @@ -219,73 +110,18 @@ open class EntryProvider : ContentProvider() { } } - private fun queryPageDebug(): Cursor { - val entryRepository by spaEnvironment.entryRepository - val cursor = MatrixCursor(QueryEnum.PAGE_DEBUG_QUERY.getColumns()) - for (pageWithEntry in entryRepository.getAllPageWithEntry()) { - val command = createBrowsePageAdbCommand(pageWithEntry.page) - if (command != null) { - cursor.newRow().add(ColumnEnum.PAGE_START_ADB.id, command) - } - } - return cursor - } - - private fun queryEntryDebug(): Cursor { - val entryRepository by spaEnvironment.entryRepository - val cursor = MatrixCursor(QueryEnum.ENTRY_DEBUG_QUERY.getColumns()) - for (entry in entryRepository.getAllEntries()) { - val command = createBrowsePageAdbCommand(entry.containerPage(), entry.id) - if (command != null) { - cursor.newRow().add(ColumnEnum.ENTRY_START_ADB.id, command) - } - } - return cursor - } - - private fun queryPageInfo(): Cursor { - val entryRepository by spaEnvironment.entryRepository - val cursor = MatrixCursor(QueryEnum.PAGE_INFO_QUERY.getColumns()) - for (pageWithEntry in entryRepository.getAllPageWithEntry()) { - val page = pageWithEntry.page - cursor.newRow() - .add(ColumnEnum.PAGE_ID.id, page.id) - .add(ColumnEnum.PAGE_NAME.id, page.displayName) - .add(ColumnEnum.PAGE_ROUTE.id, page.buildRoute()) - .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 queryEntryInfo(): Cursor { - val entryRepository by spaEnvironment.entryRepository - val cursor = MatrixCursor(QueryEnum.ENTRY_INFO_QUERY.getColumns()) - for (entry in entryRepository.getAllEntries()) { - cursor.newRow() - .add(ColumnEnum.ENTRY_ID.id, entry.id) - .add(ColumnEnum.ENTRY_NAME.id, entry.displayName) - .add(ColumnEnum.ENTRY_ROUTE.id, entry.containerPage().buildRoute()) - .add( - ColumnEnum.ENTRY_INTENT_URI.id, - createBrowsePageIntent(entry.containerPage(), entry.id).toUri(URI_INTENT_SCHEME) - ) - } - return cursor - } - private fun querySearchSitemap(): Cursor { val entryRepository by spaEnvironment.entryRepository val cursor = MatrixCursor(QueryEnum.SEARCH_SITEMAP_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)) } return cursor } @@ -321,54 +157,4 @@ open class EntryProvider : ContentProvider() { searchData?.keyword ?: emptyList<String>() ) } - - private fun createBrowsePageIntent(page: SettingsPage, entryId: String? = null): Intent { - if (!isPageBrowsable(page)) return Intent() - return Intent().setComponent(ComponentName(context!!, spaEnvironment.browseActivityClass!!)) - .apply { - putExtra(BrowseActivity.KEY_DESTINATION, page.buildRoute()) - if (entryId != null) { - putExtra(BrowseActivity.KEY_HIGHLIGHT_ENTRY, entryId) - } - } - } - - private fun createBrowsePageAdbCommand(page: SettingsPage, entryId: String? = null): String? { - if (!isPageBrowsable(page)) return null - val packageName = context!!.packageName - val activityName = spaEnvironment.browseActivityClass!!.name.replace(packageName, "") - val destinationParam = " -e ${BrowseActivity.KEY_DESTINATION} ${page.buildRoute()}" - val highlightParam = - if (entryId != null) " -e ${BrowseActivity.KEY_HIGHLIGHT_ENTRY} $entryId" else "" - return "adb shell am start -n $packageName/$activityName$destinationParam$highlightParam" - } - - private fun isPageBrowsable(page: SettingsPage): Boolean { - return context != null && - spaEnvironment.browseActivityClass != null && - !page.hasRuntimeParam() - } -} - -fun EntryProvider.QueryEnum.getColumns(): Array<String> { - return columnNames.map { it.id }.toTypedArray() -} - -fun EntryProvider.QueryEnum.getIndex(name: EntryProvider.ColumnEnum): Int { - return columnNames.indexOf(name) -} - -fun Cursor.getString(query: EntryProvider.QueryEnum, columnName: EntryProvider.ColumnEnum): String { - return this.getString(query.getIndex(columnName)) -} - -fun Cursor.getInt(query: EntryProvider.QueryEnum, columnName: EntryProvider.ColumnEnum): Int { - return this.getInt(query.getIndex(columnName)) -} - -fun Cursor.getBoolean( - query: EntryProvider.QueryEnum, - columnName: EntryProvider.ColumnEnum -): Boolean { - return this.getInt(query.getIndex(columnName)) == 1 } diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/ProviderColumn.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/ProviderColumn.kt new file mode 100644 index 000000000000..0707429505c8 --- /dev/null +++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/ProviderColumn.kt @@ -0,0 +1,126 @@ +/* + * 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.content.UriMatcher + +/** + * Enum to define all column names in provider. + */ +enum class ColumnEnum(val id: String) { + // Columns related to page + PAGE_ID("pageId"), + PAGE_NAME("pageName"), + PAGE_ROUTE("pageRoute"), + PAGE_INTENT_URI("pageIntent"), + PAGE_ENTRY_COUNT("entryCount"), + HAS_RUNTIME_PARAM("hasRuntimeParam"), + PAGE_START_ADB("pageStartAdb"), + + // Columns related to entry + ENTRY_ID("entryId"), + ENTRY_NAME("entryName"), + ENTRY_ROUTE("entryRoute"), + ENTRY_INTENT_URI("entryIntent"), + ENTRY_HIERARCHY_PATH("entryPath"), + ENTRY_START_ADB("entryStartAdb"), + + // Columns related to search + ENTRY_TITLE("entryTitle"), + ENTRY_SEARCH_KEYWORD("entrySearchKw"), +} + +/** + * Enum to define all queries supported in the provider. + */ +enum class QueryEnum( + val queryPath: String, + val queryMatchCode: Int, + val columnNames: List<ColumnEnum> +) { + // For debug + PAGE_DEBUG_QUERY( + "page_debug", 1, + listOf(ColumnEnum.PAGE_START_ADB) + ), + ENTRY_DEBUG_QUERY( + "entry_debug", 2, + listOf(ColumnEnum.ENTRY_START_ADB) + ), + + // page related queries. + PAGE_INFO_QUERY( + "page_info", 100, + listOf( + ColumnEnum.PAGE_ID, + ColumnEnum.PAGE_NAME, + ColumnEnum.PAGE_ROUTE, + ColumnEnum.PAGE_INTENT_URI, + ColumnEnum.PAGE_ENTRY_COUNT, + ColumnEnum.HAS_RUNTIME_PARAM, + ) + ), + + // entry related queries + ENTRY_INFO_QUERY( + "entry_info", 200, + listOf( + ColumnEnum.ENTRY_ID, + ColumnEnum.ENTRY_NAME, + ColumnEnum.ENTRY_ROUTE, + ColumnEnum.ENTRY_INTENT_URI, + ) + ), + + // 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, + ) + ), + SEARCH_DYNAMIC_DATA_QUERY( + "search_dynamic", 302, + listOf( + ColumnEnum.ENTRY_ID, + ColumnEnum.ENTRY_TITLE, + ColumnEnum.ENTRY_SEARCH_KEYWORD, + ) + ), +} + +internal fun QueryEnum.getColumns(): Array<String> { + return columnNames.map { it.id }.toTypedArray() +} + +internal fun QueryEnum.getIndex(name: ColumnEnum): Int { + return columnNames.indexOf(name) +} + +internal fun QueryEnum.addUri(uriMatcher: UriMatcher, authority: String) { + uriMatcher.addURI(authority, queryPath, queryMatchCode) +} diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsPage.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsPage.kt index 8f63c47b1a9b..07df96e778c4 100644 --- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsPage.kt +++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsPage.kt @@ -16,8 +16,13 @@ package com.android.settingslib.spa.framework.common +import android.app.Activity +import android.content.ComponentName +import android.content.Context +import android.content.Intent import android.os.Bundle import androidx.navigation.NamedNavArgument +import com.android.settingslib.spa.framework.BrowseActivity import com.android.settingslib.spa.framework.util.isRuntimeParam import com.android.settingslib.spa.framework.util.navLink import com.android.settingslib.spa.framework.util.normalize @@ -111,6 +116,41 @@ data class SettingsPage( details = formatDisplayTitle() ) } + + fun createBrowseIntent( + context: Context?, + browseActivityClass: Class<out Activity>?, + entryId: String? = null + ): Intent? { + if (!isBrowsable(context, browseActivityClass)) return null + return Intent().setComponent(ComponentName(context!!, browseActivityClass!!)) + .apply { + putExtra(BrowseActivity.KEY_DESTINATION, buildRoute()) + if (entryId != null) { + putExtra(BrowseActivity.KEY_HIGHLIGHT_ENTRY, entryId) + } + } + } + + fun createBrowseAdbCommand( + context: Context?, + browseActivityClass: Class<out Activity>?, + entryId: String? = null + ): String? { + if (!isBrowsable(context, browseActivityClass)) return null + val packageName = context!!.packageName + val activityName = browseActivityClass!!.name.replace(packageName, "") + val destinationParam = " -e ${BrowseActivity.KEY_DESTINATION} ${buildRoute()}" + val highlightParam = + if (entryId != null) " -e ${BrowseActivity.KEY_HIGHLIGHT_ENTRY} $entryId" else "" + return "adb shell am start -n $packageName/$activityName$destinationParam$highlightParam" + } + + fun isBrowsable(context: Context?, browseActivityClass: Class<out Activity>?): Boolean { + return context != null && + browseActivityClass != null && + !hasRuntimeParam() + } } fun String.toHashId(): String { diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/DebugActivity.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/debug/DebugActivity.kt index 6f968180e243..301508074f30 100644 --- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/DebugActivity.kt +++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/debug/DebugActivity.kt @@ -14,12 +14,9 @@ * limitations under the License. */ -package com.android.settingslib.spa.framework +package com.android.settingslib.spa.framework.debug -import android.content.Intent -import android.net.Uri import android.os.Bundle -import android.util.Log import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.compose.material3.Text @@ -33,8 +30,6 @@ 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.BrowseActivity.Companion.KEY_HIGHLIGHT_ENTRY import com.android.settingslib.spa.framework.common.LogCategory import com.android.settingslib.spa.framework.common.SettingsEntry import com.android.settingslib.spa.framework.common.SettingsPage @@ -60,11 +55,10 @@ private const val PARAM_NAME_ENTRY_ID = "eid" /** * The Debug Activity to display all Spa Pages & Entries. * 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 + * $ adb shell am start -n <Package>/com.android.settingslib.spa.framework.debug.DebugActivity + * For gallery, Package = com.android.settingslib.spa.gallery */ -open class DebugActivity : ComponentActivity() { +class DebugActivity : ComponentActivity() { private val spaEnvironment get() = SpaEnvironmentFactory.instance override fun onCreate(savedInstanceState: Bundle?) { @@ -79,30 +73,6 @@ open class DebugActivity : ComponentActivity() { } } - private fun displayDebugMessage() { - val entryProviderAuthorities = spaEnvironment.entryProviderAuthorities ?: return - - try { - val query = EntryProvider.QueryEnum.PAGE_INFO_QUERY - contentResolver.query( - Uri.parse("content://$entryProviderAuthorities/${query.queryPath}"), - null, null, null - ).use { cursor -> - while (cursor != null && cursor.moveToNext()) { - val route = cursor.getString(query, EntryProvider.ColumnEnum.PAGE_ROUTE) - val entryCount = cursor.getInt(query, EntryProvider.ColumnEnum.PAGE_ENTRY_COUNT) - val hasRuntimeParam = - cursor.getBoolean(query, EntryProvider.ColumnEnum.HAS_RUNTIME_PARAM) - val message = "Page Info: $route ($entryCount) " + - (if (hasRuntimeParam) "with" else "no") + "-runtime-params" - spaEnvironment.logger.message(TAG, message, category = LogCategory.FRAMEWORK) - } - } - } catch (e: Exception) { - Log.e(TAG, "Provider querying exception:", e) - } - } - @Composable private fun MainContent() { val navController = rememberNavController() @@ -141,11 +111,6 @@ open class DebugActivity : ComponentActivity() { override val title = "List All Entries (${allEntry.size})" override val onClick = navigator(route = ROUTE_All_ENTRIES) }) - Preference(object : PreferenceModel { - override val title = "Query EntryProvider" - override val enabled = isEntryProviderAvailable().toState() - override val onClick = { displayDebugMessage() } - }) } } @@ -177,6 +142,7 @@ open class DebugActivity : ComponentActivity() { @Composable fun OnePage(arguments: Bundle?) { + val context = LocalContext.current val entryRepository by spaEnvironment.entryRepository val id = arguments!!.getString(PARAM_NAME_PAGE_ID, "") val pageWithEntry = entryRepository.getPageWithEntry(id)!! @@ -186,7 +152,9 @@ open class DebugActivity : ComponentActivity() { Text(text = "Entry size: ${pageWithEntry.entries.size}") Preference(model = object : PreferenceModel { override val title = "open page" - override val enabled = isPageClickable(pageWithEntry.page).toState() + override val enabled = + pageWithEntry.page.isBrowsable(context, spaEnvironment.browseActivityClass) + .toState() override val onClick = openPage(pageWithEntry.page) }) EntryList(pageWithEntry.entries) @@ -195,6 +163,7 @@ open class DebugActivity : ComponentActivity() { @Composable fun OneEntry(arguments: Bundle?) { + val context = LocalContext.current val entryRepository by spaEnvironment.entryRepository val id = arguments!!.getString(PARAM_NAME_ENTRY_ID, "") val entry = entryRepository.getEntry(id)!! @@ -202,7 +171,9 @@ open class DebugActivity : ComponentActivity() { RegularScaffold(title = "Entry - ${entry.displayTitle()}") { Preference(model = object : PreferenceModel { override val title = "open entry" - override val enabled = isEntryClickable(entry).toState() + override val enabled = + entry.containerPage().isBrowsable(context, spaEnvironment.browseActivityClass) + .toState() override val onClick = openEntry(entry) }) Text(text = entryContent) @@ -223,12 +194,10 @@ open class DebugActivity : ComponentActivity() { @Composable private fun openPage(page: SettingsPage): (() -> Unit)? { - if (!isPageClickable(page)) return null val context = LocalContext.current + val intent = + page.createBrowseIntent(context, spaEnvironment.browseActivityClass) ?: return null val route = page.buildRoute() - val intent = Intent(context, spaEnvironment.browseActivityClass).apply { - putExtra(KEY_DESTINATION, route) - } return { spaEnvironment.logger.message( TAG, "OpenPage: $route", category = LogCategory.FRAMEWORK @@ -239,13 +208,11 @@ open class DebugActivity : ComponentActivity() { @Composable private fun openEntry(entry: SettingsEntry): (() -> Unit)? { - if (!isEntryClickable(entry)) return null val context = LocalContext.current + val intent = entry.containerPage() + .createBrowseIntent(context, spaEnvironment.browseActivityClass, entry.id) + ?: return null val route = entry.containerPage().buildRoute() - val intent = Intent(context, spaEnvironment.browseActivityClass).apply { - putExtra(KEY_DESTINATION, route) - putExtra(KEY_HIGHLIGHT_ENTRY, entry.id) - } return { spaEnvironment.logger.message( TAG, "OpenEntry: $route", category = LogCategory.FRAMEWORK @@ -253,17 +220,9 @@ open class DebugActivity : ComponentActivity() { context.startActivity(intent) } } - - private fun isEntryProviderAvailable(): Boolean { - return spaEnvironment.entryProviderAuthorities != null - } - - private fun isPageClickable(page: SettingsPage): Boolean { - return spaEnvironment.browseActivityClass != null && !page.hasRuntimeParam() - } - - private fun isEntryClickable(entry: SettingsEntry): Boolean { - return spaEnvironment.browseActivityClass != null && - !entry.containerPage().hasRuntimeParam() - } } + +/** + * A blank activity without any page. + */ +class BlankActivity : ComponentActivity() diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/debug/DebugProvider.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/debug/DebugProvider.kt new file mode 100644 index 000000000000..6c271094de9f --- /dev/null +++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/debug/DebugProvider.kt @@ -0,0 +1,176 @@ +/* + * 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.debug + +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 +import android.database.MatrixCursor +import android.net.Uri +import android.util.Log +import com.android.settingslib.spa.framework.common.ColumnEnum +import com.android.settingslib.spa.framework.common.QueryEnum +import com.android.settingslib.spa.framework.common.SpaEnvironmentFactory +import com.android.settingslib.spa.framework.common.addUri +import com.android.settingslib.spa.framework.common.getColumns + +private const val TAG = "DebugProvider" + +/** + * The content provider to return debug data. + * One can query the provider result by: + * $ adb shell content query --uri content://<AuthorityPath>/<QueryPath> + * For gallery, AuthorityPath = com.android.spa.gallery.debug + * Some examples: + * $ adb shell content query --uri content://<AuthorityPath>/page_debug + * $ adb shell content query --uri content://<AuthorityPath>/entry_debug + * $ adb shell content query --uri content://<AuthorityPath>/page_info + * $ adb shell content query --uri content://<AuthorityPath>/entry_info + */ +class DebugProvider : ContentProvider() { + private val spaEnvironment get() = SpaEnvironmentFactory.instance + private val uriMatcher = UriMatcher(UriMatcher.NO_MATCH) + + override fun delete(uri: Uri, selection: String?, selectionArgs: Array<String>?): Int { + TODO("Implement this to handle requests to delete one or more rows") + } + + override fun getType(uri: Uri): String? { + TODO( + "Implement this to handle requests for the MIME type of the data" + + "at the given URI" + ) + } + + override fun insert(uri: Uri, values: ContentValues?): Uri? { + TODO("Implement this to handle requests to insert a new row.") + } + + override fun update( + uri: Uri, + values: ContentValues?, + selection: String?, + selectionArgs: Array<String>? + ): Int { + TODO("Implement this to handle requests to update one or more rows.") + } + + override fun onCreate(): Boolean { + Log.d(TAG, "onCreate") + return true + } + + override fun attachInfo(context: Context?, info: ProviderInfo?) { + if (info != null) { + QueryEnum.PAGE_DEBUG_QUERY.addUri(uriMatcher, info.authority) + QueryEnum.ENTRY_DEBUG_QUERY.addUri(uriMatcher, info.authority) + QueryEnum.PAGE_INFO_QUERY.addUri(uriMatcher, info.authority) + QueryEnum.ENTRY_INFO_QUERY.addUri(uriMatcher, info.authority) + } + super.attachInfo(context, info) + } + + override fun query( + uri: Uri, + projection: Array<String>?, + selection: String?, + selectionArgs: Array<String>?, + sortOrder: String? + ): Cursor? { + return try { + when (uriMatcher.match(uri)) { + QueryEnum.PAGE_DEBUG_QUERY.queryMatchCode -> queryPageDebug() + QueryEnum.ENTRY_DEBUG_QUERY.queryMatchCode -> queryEntryDebug() + QueryEnum.PAGE_INFO_QUERY.queryMatchCode -> queryPageInfo() + QueryEnum.ENTRY_INFO_QUERY.queryMatchCode -> queryEntryInfo() + else -> throw UnsupportedOperationException("Unknown Uri $uri") + } + } catch (e: UnsupportedOperationException) { + throw e + } catch (e: Exception) { + Log.e(TAG, "Provider querying exception:", e) + null + } + } + + private fun queryPageDebug(): Cursor { + val entryRepository by spaEnvironment.entryRepository + val cursor = MatrixCursor(QueryEnum.PAGE_DEBUG_QUERY.getColumns()) + for (pageWithEntry in entryRepository.getAllPageWithEntry()) { + val command = pageWithEntry.page.createBrowseAdbCommand( + context, + spaEnvironment.browseActivityClass + ) + if (command != null) { + cursor.newRow().add(ColumnEnum.PAGE_START_ADB.id, command) + } + } + return cursor + } + + private fun queryEntryDebug(): Cursor { + val entryRepository by spaEnvironment.entryRepository + val cursor = MatrixCursor(QueryEnum.ENTRY_DEBUG_QUERY.getColumns()) + for (entry in entryRepository.getAllEntries()) { + val command = entry.containerPage() + .createBrowseAdbCommand(context, spaEnvironment.browseActivityClass, entry.id) + if (command != null) { + cursor.newRow().add(ColumnEnum.ENTRY_START_ADB.id, command) + } + } + return cursor + } + + private fun queryPageInfo(): Cursor { + val entryRepository by spaEnvironment.entryRepository + val cursor = MatrixCursor(QueryEnum.PAGE_INFO_QUERY.getColumns()) + for (pageWithEntry in entryRepository.getAllPageWithEntry()) { + val page = pageWithEntry.page + val intent = + page.createBrowseIntent(context, spaEnvironment.browseActivityClass) ?: Intent() + cursor.newRow() + .add(ColumnEnum.PAGE_ID.id, page.id) + .add(ColumnEnum.PAGE_NAME.id, page.displayName) + .add(ColumnEnum.PAGE_ROUTE.id, page.buildRoute()) + .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, intent.toUri(URI_INTENT_SCHEME)) + } + return cursor + } + + private fun queryEntryInfo(): Cursor { + val entryRepository by spaEnvironment.entryRepository + val cursor = MatrixCursor(QueryEnum.ENTRY_INFO_QUERY.getColumns()) + for (entry in entryRepository.getAllEntries()) { + val intent = entry.containerPage() + .createBrowseIntent(context, spaEnvironment.browseActivityClass, entry.id) + ?: Intent() + cursor.newRow() + .add(ColumnEnum.ENTRY_ID.id, entry.id) + .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)) + } + return cursor + } +} |