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

Commit edcfec0f authored by Zekan Qian's avatar Zekan Qian
Browse files

Add SpaIntent for all intent operator in Spa

Support Session Name in SpaIntent
Add tests for SpaIntent
Set proper Session Name in DebugActivity, SpaSearchProvider & SliceUtil

Bug: 244122804
Test: unit-test & local build gallery
Change-Id: Ia9c21e2f56dcf7b4437e5bb417bdfe05b7c85b77
parent 28bd0458
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ import com.android.settingslib.spa.framework.common.SpaEnvironmentFactory
import com.android.settingslib.spa.framework.common.createSettingsPage
import com.android.settingslib.spa.framework.compose.toState
import com.android.settingslib.spa.framework.theme.SettingsTheme
import com.android.settingslib.spa.framework.util.createIntent
import com.android.settingslib.spa.gallery.R
import com.android.settingslib.spa.gallery.SettingsPageProviderEnum
import com.android.settingslib.spa.gallery.preference.PreferencePageModel.Companion.ASYNC_PREFERENCE_SUMMARY
@@ -91,6 +92,7 @@ object PreferencePageProvider : SettingsPageProvider {
                    spaLogger.message(TAG, "create macro for ${EntryEnum.SIMPLE_PREFERENCE}")
                    SimplePreferenceMacro(title = SIMPLE_PREFERENCE_TITLE)
                }
                .setStatusDataFn { EntryStatusData(isDisabled = false) }
                .build()
        )
        entryList.add(
@@ -103,6 +105,7 @@ object PreferencePageProvider : SettingsPageProvider {
                        searchKeywords = SIMPLE_PREFERENCE_KEYWORDS,
                    )
                }
                .setStatusDataFn { EntryStatusData(isDisabled = true) }
                .build()
        )
        entryList.add(singleLineSummaryEntry())
@@ -269,7 +272,7 @@ object PreferencePageProvider : SettingsPageProvider {
                )
            }
            .setSliceDataFn { sliceUri, _ ->
                val intent = owner.createBrowseIntent()?.createBrowsePendingIntent()
                val intent = owner.createIntent()?.createBrowsePendingIntent()
                    ?: return@setSliceDataFn null
                return@setSliceDataFn object : EntrySliceData() {
                    init {
+12 −24
Original line number Diff line number Diff line
@@ -39,7 +39,10 @@ import com.android.settingslib.spa.framework.compose.localNavController
import com.android.settingslib.spa.framework.compose.navigator
import com.android.settingslib.spa.framework.compose.toState
import com.android.settingslib.spa.framework.theme.SettingsTheme
import com.android.settingslib.spa.slice.appendSliceParams
import com.android.settingslib.spa.framework.util.SESSION_BROWSE
import com.android.settingslib.spa.framework.util.SESSION_SEARCH
import com.android.settingslib.spa.framework.util.createIntent
import com.android.settingslib.spa.slice.fromEntry
import com.android.settingslib.spa.slice.presenter.SliceDemo
import com.android.settingslib.spa.widget.preference.Preference
import com.android.settingslib.spa.widget.preference.PreferenceModel
@@ -158,14 +161,13 @@ class DebugActivity : ComponentActivity() {
            remember { entryRepository.getAllEntries().filter { it.hasSliceSupport } }
        RegularScaffold(title = "All Slices (${allSliceEntry.size})") {
            for (entry in allSliceEntry) {
                SliceDemo(sliceUri = entry.createSliceUri(authority))
                SliceDemo(sliceUri = Uri.Builder().fromEntry(entry, authority).build())
            }
        }
    }

    @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)!!
@@ -176,8 +178,8 @@ class DebugActivity : ComponentActivity() {
            Text(text = "Entry size: ${pageWithEntry.entries.size}")
            Preference(model = object : PreferenceModel {
                override val title = "open page"
                override val enabled =
                    page.isBrowsable(context, spaEnvironment.browseActivityClass).toState()
                override val enabled = (spaEnvironment.browseActivityClass != null &&
                    page.isBrowsable()).toState()
                override val onClick = openPage(page)
            })
            EntryList(pageWithEntry.entries)
@@ -186,7 +188,6 @@ 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)!!
@@ -194,8 +195,8 @@ class DebugActivity : ComponentActivity() {
        RegularScaffold(title = "Entry - ${entry.debugBrief()}") {
            Preference(model = object : PreferenceModel {
                override val title = "open entry"
                override val enabled =
                    entry.containerPage().isBrowsable(context, spaEnvironment.browseActivityClass)
                override val enabled = (spaEnvironment.browseActivityClass != null &&
                    entry.containerPage().isBrowsable())
                    .toState()
                override val onClick = openEntry(entry)
            })
@@ -219,7 +220,7 @@ class DebugActivity : ComponentActivity() {
    private fun openPage(page: SettingsPage): (() -> Unit)? {
        val context = LocalContext.current
        val intent =
            page.createBrowseIntent(context, spaEnvironment.browseActivityClass) ?: return null
            page.createIntent(SESSION_BROWSE) ?: return null
        val route = page.buildRoute()
        return {
            spaEnvironment.logger.message(
@@ -232,8 +233,7 @@ class DebugActivity : ComponentActivity() {
    @Composable
    private fun openEntry(entry: SettingsEntry): (() -> Unit)? {
        val context = LocalContext.current
        val intent = entry.containerPage()
            .createBrowseIntent(context, spaEnvironment.browseActivityClass, entry.id)
        val intent = entry.createIntent(SESSION_SEARCH)
            ?: return null
        val route = entry.containerPage().buildRoute()
        return {
@@ -245,18 +245,6 @@ class DebugActivity : ComponentActivity() {
    }
}

private fun SettingsEntry.createSliceUri(
    authority: String?,
    runtimeArguments: Bundle? = null
): Uri {
    if (authority == null) return Uri.EMPTY
    return Uri.Builder().scheme("content").authority(authority).appendSliceParams(
        route = this.containerPage().buildRoute(),
        entryId = this.id,
        runtimeArguments = runtimeArguments,
    ).build()
}

/**
 * A blank activity without any page.
 */
+43 −12
Original line number Diff line number Diff line
@@ -32,6 +32,12 @@ 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
import com.android.settingslib.spa.framework.util.KEY_DESTINATION
import com.android.settingslib.spa.framework.util.KEY_HIGHLIGHT_ENTRY
import com.android.settingslib.spa.framework.util.KEY_SESSION_SOURCE_NAME
import com.android.settingslib.spa.framework.util.SESSION_BROWSE
import com.android.settingslib.spa.framework.util.SESSION_SEARCH
import com.android.settingslib.spa.framework.util.createIntent

private const val TAG = "DebugProvider"

@@ -116,9 +122,11 @@ class DebugProvider : ContentProvider() {
        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
            val page = pageWithEntry.page
            if (!page.isBrowsable()) continue
            val command = createBrowseAdbCommand(
                destination = page.buildRoute(),
                sessionName = SESSION_BROWSE
            )
            if (command != null) {
                cursor.newRow().add(ColumnEnum.PAGE_START_ADB.id, command)
@@ -131,8 +139,13 @@ class DebugProvider : ContentProvider() {
        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)
            val page = entry.containerPage()
            if (!page.isBrowsable()) continue
            val command = createBrowseAdbCommand(
                destination = page.buildRoute(),
                entryId = entry.id,
                sessionName = SESSION_SEARCH
            )
            if (command != null) {
                cursor.newRow().add(ColumnEnum.ENTRY_START_ADB.id, command)
            }
@@ -145,8 +158,7 @@ class DebugProvider : ContentProvider() {
        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()
            val intent = page.createIntent(SESSION_BROWSE) ?: Intent()
            cursor.newRow()
                .add(ColumnEnum.PAGE_ID.id, page.id)
                .add(ColumnEnum.PAGE_NAME.id, page.displayName)
@@ -162,17 +174,36 @@ class DebugProvider : ContentProvider() {
        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()
            val intent = entry.createIntent(SESSION_SEARCH) ?: 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))
                .add(ColumnEnum.ENTRY_HIERARCHY_PATH.id,
                    entryRepository.getEntryPathWithDisplayName(entry.id))
                .add(
                    ColumnEnum.ENTRY_HIERARCHY_PATH.id,
                    entryRepository.getEntryPathWithDisplayName(entry.id)
                )
        }
        return cursor
    }
}

private fun createBrowseAdbCommand(
    destination: String? = null,
    entryId: String? = null,
    sessionName: String? = null,
): String? {
    val context = SpaEnvironmentFactory.instance.appContext
    val browseActivityClass = SpaEnvironmentFactory.instance.browseActivityClass ?: return null
    val packageName = context.packageName
    val activityName = browseActivityClass.name.replace(packageName, "")
    val destinationParam =
        if (destination != null) " -e $KEY_DESTINATION $destination" else ""
    val highlightParam =
        if (entryId != null) " -e $KEY_HIGHLIGHT_ENTRY $entryId" else ""
    val sessionParam =
        if (sessionName != null) " -e $KEY_SESSION_SOURCE_NAME $sessionName" else ""
    return "adb shell am start -n $packageName/$activityName" +
        "$destinationParam$highlightParam$sessionParam"
}
+6 −10
Original line number Diff line number Diff line
@@ -42,6 +42,9 @@ import com.android.settingslib.spa.framework.compose.NavControllerWrapperImpl
import com.android.settingslib.spa.framework.compose.localNavController
import com.android.settingslib.spa.framework.theme.SettingsTheme
import com.android.settingslib.spa.framework.util.PageEvent
import com.android.settingslib.spa.framework.util.getDestination
import com.android.settingslib.spa.framework.util.getEntryId
import com.android.settingslib.spa.framework.util.getSessionName
import com.android.settingslib.spa.framework.util.navRoute

private const val TAG = "BrowseActivity"
@@ -78,12 +81,6 @@ open class BrowseActivity : ComponentActivity() {
            }
        }
    }

    companion object {
        const val KEY_DESTINATION = "spaActivityDestination"
        const val KEY_HIGHLIGHT_ENTRY = "highlightEntry"
        const val KEY_SESSION_SOURCE_NAME = "sessionSource"
    }
}

@VisibleForTesting
@@ -126,11 +123,10 @@ private fun NavControllerWrapperImpl.InitialDestination(
    if (destinationNavigated.value) return
    destinationNavigated.value = true

    val initialDestination = initialIntent?.getStringExtra(BrowseActivity.KEY_DESTINATION)
        ?: defaultDestination
    val initialDestination = initialIntent?.getDestination() ?: defaultDestination
    if (initialDestination.isEmpty()) return
    val initialEntryId = initialIntent?.getStringExtra(BrowseActivity.KEY_HIGHLIGHT_ENTRY)
    val sessionSourceName = initialIntent?.getStringExtra(BrowseActivity.KEY_SESSION_SOURCE_NAME)
    val initialEntryId = initialIntent?.getEntryId()
    val sessionSourceName = initialIntent?.getSessionName()

    LaunchedEffect(Unit) {
        highlightId = initialEntryId
+2 −44
Original line number Diff line number Diff line
@@ -16,13 +16,8 @@

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
@@ -95,45 +90,8 @@ data class SettingsPage(
        return false
    }

    fun createBrowseIntent(entryId: String? = null): Intent? {
        val context = SpaEnvironmentFactory.instance.appContext
        val browseActivityClass = SpaEnvironmentFactory.instance.browseActivityClass
        return createBrowseIntent(context, browseActivityClass, entryId)
    }

    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 &&
            !isCreateBy(NULL_PAGE_NAME) &&
    fun isBrowsable(): Boolean {
        return !isCreateBy(NULL_PAGE_NAME) &&
            !hasRuntimeParam()
    }
}
Loading