Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8d502427 authored by Zekan Qian's avatar Zekan Qian Committed by Android (Google) Code Review
Browse files

Merge "Move debug related activity & provider to debug folder."

parents 314668f8 285690dc
Loading
Loading
Loading
Loading
+14 −4
Original line number Diff line number Diff line
@@ -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>
+0 −21
Original line number Diff line number Diff line
/*
 * 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()
+12 −226
Original line number Diff line number Diff line
@@ -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
}
+126 −0
Original line number Diff line number Diff line
/*
 * 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)
}
+40 −0
Original line number Diff line number Diff line
@@ -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 {
Loading