Merge "Add SpaIntent for all intent operator in Spa"

This commit is contained in:
Zekan Qian
2022-12-01 00:25:30 +00:00
committed by Android (Google) Code Review
16 changed files with 273 additions and 142 deletions

View File

@@ -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 {

View File

@@ -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,9 +195,9 @@ 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)
.toState()
override val enabled = (spaEnvironment.browseActivityClass != null &&
entry.containerPage().isBrowsable())
.toState()
override val onClick = openEntry(entry)
})
Text(text = entryContent)
@@ -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.
*/

View File

@@ -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"
}

View File

@@ -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

View File

@@ -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()
}
}

View File

@@ -0,0 +1,85 @@
/*
* 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.util
import android.content.ComponentName
import android.content.Intent
import com.android.settingslib.spa.framework.common.SettingsEntry
import com.android.settingslib.spa.framework.common.SettingsPage
import com.android.settingslib.spa.framework.common.SpaEnvironmentFactory
const val SESSION_BROWSE = "browse"
const val SESSION_SEARCH = "search"
const val SESSION_SLICE = "slice"
const val KEY_DESTINATION = "spaActivityDestination"
const val KEY_HIGHLIGHT_ENTRY = "highlightEntry"
const val KEY_SESSION_SOURCE_NAME = "sessionSource"
val SPA_INTENT_RESERVED_KEYS = listOf(
KEY_DESTINATION,
KEY_HIGHLIGHT_ENTRY,
KEY_SESSION_SOURCE_NAME
)
private fun createBaseIntent(): Intent? {
val context = SpaEnvironmentFactory.instance.appContext
val browseActivityClass = SpaEnvironmentFactory.instance.browseActivityClass ?: return null
return Intent().setComponent(ComponentName(context, browseActivityClass))
}
fun SettingsPage.createIntent(sessionName: String? = null): Intent? {
if (!isBrowsable()) return null
return createBaseIntent()?.appendSpaParams(
destination = buildRoute(),
sessionName = sessionName
)
}
fun SettingsEntry.createIntent(sessionName: String? = null): Intent? {
val sp = containerPage()
if (!sp.isBrowsable()) return null
return createBaseIntent()?.appendSpaParams(
destination = sp.buildRoute(),
entryId = id,
sessionName = sessionName
)
}
fun Intent.appendSpaParams(
destination: String? = null,
entryId: String? = null,
sessionName: String? = null
): Intent {
return apply {
if (destination != null) putExtra(KEY_DESTINATION, destination)
if (entryId != null) putExtra(KEY_HIGHLIGHT_ENTRY, entryId)
if (sessionName != null) putExtra(KEY_SESSION_SOURCE_NAME, sessionName)
}
}
fun Intent.getDestination(): String? {
return getStringExtra(KEY_DESTINATION)
}
fun Intent.getEntryId(): String? {
return getStringExtra(KEY_HIGHLIGHT_ENTRY)
}
fun Intent.getSessionName(): String? {
return getStringExtra(KEY_SESSION_SOURCE_NAME)
}

View File

@@ -33,6 +33,8 @@ import com.android.settingslib.spa.framework.common.SettingsEntry
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.SESSION_SEARCH
import com.android.settingslib.spa.framework.util.createIntent
private const val TAG = "SpaSearchProvider"
@@ -162,20 +164,19 @@ class SpaSearchProvider : 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() ?: return
val intent = entry.containerPage()
.createBrowseIntent(context, browseActivityClass, entry.id)
?: Intent()
val intent = entry.createIntent(SESSION_SEARCH) ?: Intent()
cursor.newRow()
.add(ColumnEnum.ENTRY_ID.id, entry.id)
.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.getEntryPathWithTitle(entry.id, searchData.title))
.add(
ColumnEnum.SEARCH_PATH.id,
entryRepository.getEntryPathWithTitle(entry.id, searchData.title)
)
}
private fun fetchStatusData(entry: SettingsEntry, cursor: MatrixCursor) {

View File

@@ -20,6 +20,7 @@ import android.net.Uri
import android.util.Log
import com.android.settingslib.spa.framework.common.EntrySliceData
import com.android.settingslib.spa.framework.common.SettingsEntryRepository
import com.android.settingslib.spa.framework.util.getEntryId
private const val TAG = "SliceDataRepository"

View File

@@ -24,9 +24,15 @@ import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Bundle
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.SettingsEntry
import com.android.settingslib.spa.framework.common.SpaEnvironmentFactory
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.SESSION_SLICE
import com.android.settingslib.spa.framework.util.SPA_INTENT_RESERVED_KEYS
import com.android.settingslib.spa.framework.util.appendSpaParams
import com.android.settingslib.spa.framework.util.getDestination
import com.android.settingslib.spa.framework.util.getEntryId
// Defines SliceUri, which contains special query parameters:
// -- KEY_DESTINATION: The route that this slice is navigated to.
@@ -35,11 +41,6 @@ import com.android.settingslib.spa.framework.common.SpaEnvironmentFactory
// Use {entryId, runtimeParams} as the unique Id of this Slice.
typealias SliceUri = Uri
val RESERVED_KEYS = listOf(
KEY_DESTINATION,
KEY_HIGHLIGHT_ENTRY
)
fun SliceUri.getEntryId(): String? {
return getQueryParameter(KEY_HIGHLIGHT_ENTRY)
}
@@ -51,7 +52,7 @@ fun SliceUri.getDestination(): String? {
fun SliceUri.getRuntimeArguments(): Bundle {
val params = Bundle()
for (queryName in queryParameterNames) {
if (RESERVED_KEYS.contains(queryName)) continue
if (SPA_INTENT_RESERVED_KEYS.contains(queryName)) continue
params.putString(queryName, getQueryParameter(queryName))
}
return params
@@ -63,12 +64,12 @@ fun SliceUri.getSliceId(): String? {
return "${entryId}_$params"
}
fun Uri.Builder.appendSliceParams(
route: String? = null,
fun Uri.Builder.appendSpaParams(
destination: String? = null,
entryId: String? = null,
runtimeArguments: Bundle? = null
): Uri.Builder {
if (route != null) appendQueryParameter(KEY_DESTINATION, route)
if (destination != null) appendQueryParameter(KEY_DESTINATION, destination)
if (entryId != null) appendQueryParameter(KEY_HIGHLIGHT_ENTRY, entryId)
if (runtimeArguments != null) {
for (key in runtimeArguments.keySet()) {
@@ -78,6 +79,20 @@ fun Uri.Builder.appendSliceParams(
return this
}
fun Uri.Builder.fromEntry(
entry: SettingsEntry,
authority: String?,
runtimeArguments: Bundle? = null
): Uri.Builder {
if (authority == null) return this
val sp = entry.containerPage()
return scheme("content").authority(authority).appendSpaParams(
destination = sp.buildRoute(),
entryId = entry.id,
runtimeArguments = runtimeArguments
)
}
fun SliceUri.createBroadcastPendingIntent(): PendingIntent? {
val context = SpaEnvironmentFactory.instance.appContext
val sliceBroadcastClass =
@@ -97,8 +112,8 @@ fun SliceUri.createBrowsePendingIntent(): PendingIntent? {
fun Intent.createBrowsePendingIntent(): PendingIntent? {
val context = SpaEnvironmentFactory.instance.appContext
val browseActivityClass = SpaEnvironmentFactory.instance.browseActivityClass ?: return null
val destination = getStringExtra(KEY_DESTINATION) ?: return null
val entryId = getStringExtra(KEY_HIGHLIGHT_ENTRY)
val destination = getDestination() ?: return null
val entryId = getEntryId()
return createBrowsePendingIntent(context, browseActivityClass, destination, entryId)
}
@@ -109,15 +124,12 @@ private fun createBrowsePendingIntent(
entryId: String?
): PendingIntent {
val intent = Intent().setComponent(ComponentName(context, browseActivityClass))
.appendSpaParams(destination, entryId, SESSION_SLICE)
.apply {
// Set both extra and data (which is a Uri) in Slice Intent:
// 1) extra is used in SPA navigation framework
// 2) data is used in Slice framework
putExtra(KEY_DESTINATION, destination)
if (entryId != null) {
putExtra(KEY_HIGHLIGHT_ENTRY, entryId)
}
data = Uri.Builder().appendSliceParams(destination, entryId).build()
data = Uri.Builder().appendSpaParams(destination, entryId).build()
flags = Intent.FLAG_ACTIVITY_NEW_TASK
}
@@ -130,7 +142,7 @@ private fun createBroadcastPendingIntent(
entryId: String
): PendingIntent {
val intent = Intent().setComponent(ComponentName(context, sliceBroadcastClass))
.apply { data = Uri.Builder().appendSliceParams(entryId = entryId).build() }
.apply { data = Uri.Builder().appendSpaParams(entryId = entryId).build() }
return PendingIntent.getBroadcast(
context, 0 /* requestCode */, intent,
PendingIntent.FLAG_CANCEL_CURRENT or PendingIntent.FLAG_MUTABLE

View File

@@ -23,6 +23,8 @@ import com.android.settingslib.spa.tests.testutils.SpaEnvironmentForTest
import com.android.settingslib.spa.tests.testutils.SppHome
import com.android.settingslib.spa.tests.testutils.SppLayer1
import com.android.settingslib.spa.tests.testutils.SppLayer2
import com.android.settingslib.spa.tests.testutils.getUniqueEntryId
import com.android.settingslib.spa.tests.testutils.getUniquePageId
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith

View File

@@ -20,6 +20,8 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.core.os.bundleOf
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.android.settingslib.spa.tests.testutils.getUniqueEntryId
import com.android.settingslib.spa.tests.testutils.getUniquePageId
import com.google.common.truth.Truth.assertThat
import org.junit.Rule
import org.junit.Test

View File

@@ -22,8 +22,8 @@ import androidx.navigation.NavType
import androidx.navigation.navArgument
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.android.settingslib.spa.tests.testutils.BlankActivity
import com.android.settingslib.spa.tests.testutils.SpaEnvironmentForTest
import com.android.settingslib.spa.tests.testutils.getUniquePageId
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
@@ -43,9 +43,7 @@ class SettingsPageTest {
assertThat(page.isCreateBy("NULL")).isTrue()
assertThat(page.isCreateBy("Spp")).isFalse()
assertThat(page.hasRuntimeParam()).isFalse()
assertThat(page.isBrowsable(context, BlankActivity::class.java)).isFalse()
assertThat(page.createBrowseIntent(context, BlankActivity::class.java)).isNull()
assertThat(page.createBrowseAdbCommand(context, BlankActivity::class.java)).isNull()
assertThat(page.isBrowsable()).isFalse()
}
@Test
@@ -58,11 +56,7 @@ class SettingsPageTest {
assertThat(page.isCreateBy("NULL")).isFalse()
assertThat(page.isCreateBy("mySpp")).isTrue()
assertThat(page.hasRuntimeParam()).isFalse()
assertThat(page.isBrowsable(context, BlankActivity::class.java)).isTrue()
assertThat(page.createBrowseIntent(context, BlankActivity::class.java)).isNotNull()
assertThat(page.createBrowseAdbCommand(context, BlankActivity::class.java)).contains(
"-e spaActivityDestination mySpp"
)
assertThat(page.isBrowsable()).isTrue()
}
@Test
@@ -85,11 +79,7 @@ class SettingsPageTest {
assertThat(page.buildRoute()).isEqualTo("SppWithParam/myStr/10")
assertThat(page.isCreateBy("SppWithParam")).isTrue()
assertThat(page.hasRuntimeParam()).isFalse()
assertThat(page.isBrowsable(context, BlankActivity::class.java)).isTrue()
assertThat(page.createBrowseIntent(context, BlankActivity::class.java)).isNotNull()
assertThat(page.createBrowseAdbCommand(context, BlankActivity::class.java)).contains(
"-e spaActivityDestination SppWithParam/myStr/10"
)
assertThat(page.isBrowsable()).isTrue()
}
@Test
@@ -114,8 +104,6 @@ class SettingsPageTest {
assertThat(page.buildRoute()).isEqualTo("SppWithRtParam/myStr/10/rtStr")
assertThat(page.isCreateBy("SppWithRtParam")).isTrue()
assertThat(page.hasRuntimeParam()).isTrue()
assertThat(page.isBrowsable(context, BlankActivity::class.java)).isFalse()
assertThat(page.createBrowseIntent(context, BlankActivity::class.java)).isNull()
assertThat(page.createBrowseAdbCommand(context, BlankActivity::class.java)).isNull()
assertThat(page.isBrowsable()).isFalse()
}
}

View File

@@ -0,0 +1,62 @@
/*
* 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.util
import android.content.Context
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
import com.android.settingslib.spa.framework.common.SettingsPage
import com.android.settingslib.spa.framework.common.SpaEnvironmentFactory
import com.android.settingslib.spa.tests.testutils.SpaEnvironmentForTest
import com.google.common.truth.Truth
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
class SpaIntentTest {
private val context: Context = ApplicationProvider.getApplicationContext()
private val spaEnvironment = SpaEnvironmentForTest(context)
@Before
fun setEnvironment() {
SpaEnvironmentFactory.reset(spaEnvironment)
}
@Test
fun testCreateIntent() {
val nullPage = SettingsPage.createNull()
Truth.assertThat(nullPage.createIntent()).isNull()
Truth.assertThat(SettingsEntryBuilder.createInject(nullPage).build().createIntent())
.isNull()
val page = spaEnvironment.createPage("SppHome")
val pageIntent = page.createIntent()
Truth.assertThat(pageIntent).isNotNull()
Truth.assertThat(pageIntent!!.getDestination()).isEqualTo(page.buildRoute())
Truth.assertThat(pageIntent.getEntryId()).isNull()
Truth.assertThat(pageIntent.getSessionName()).isNull()
val entry = SettingsEntryBuilder.createInject(page).build()
val entryIntent = entry.createIntent(SESSION_SEARCH)
Truth.assertThat(entryIntent).isNotNull()
Truth.assertThat(entryIntent!!.getDestination()).isEqualTo(page.buildRoute())
Truth.assertThat(entryIntent.getEntryId()).isEqualTo(entry.id)
Truth.assertThat(entryIntent.getSessionName()).isEqualTo(SESSION_SEARCH)
}
}

View File

@@ -23,11 +23,11 @@ import androidx.slice.Slice
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.android.settingslib.spa.framework.common.createSettingsPage
import com.android.settingslib.spa.framework.common.getUniqueEntryId
import com.android.settingslib.spa.testutils.InstantTaskExecutorRule
import com.android.settingslib.spa.tests.testutils.SpaEnvironmentForTest
import com.android.settingslib.spa.tests.testutils.SppHome
import com.android.settingslib.spa.tests.testutils.SppLayer2
import com.android.settingslib.spa.tests.testutils.getUniqueEntryId
import com.google.common.truth.Truth.assertThat
import org.junit.Rule
import org.junit.Test
@@ -50,7 +50,7 @@ class SettingsSliceDataRepositoryTest {
// Slice supported
val page = SppLayer2.createSettingsPage()
val entryId = getUniqueEntryId("Layer2Entry1", page)
val sliceUri = Uri.Builder().appendSliceParams(page.buildRoute(), entryId).build()
val sliceUri = Uri.Builder().appendSpaParams(page.buildRoute(), entryId).build()
assertThat(sliceUri.getDestination()).isEqualTo("SppLayer2")
assertThat(sliceUri.getSliceId()).isEqualTo("${entryId}_Bundle[{}]")
val sliceData = sliceDataRepository.getOrBuildSliceData(sliceUri)
@@ -59,7 +59,7 @@ class SettingsSliceDataRepositoryTest {
// Slice unsupported
val entryId2 = getUniqueEntryId("Layer2Entry2", page)
val sliceUri2 = Uri.Builder().appendSliceParams(page.buildRoute(), entryId2).build()
val sliceUri2 = Uri.Builder().appendSpaParams(page.buildRoute(), entryId2).build()
assertThat(sliceUri2.getDestination()).isEqualTo("SppLayer2")
assertThat(sliceUri2.getSliceId()).isEqualTo("${entryId2}_Bundle[{}]")
assertThat(sliceDataRepository.getOrBuildSliceData(sliceUri2)).isNull()
@@ -69,7 +69,7 @@ class SettingsSliceDataRepositoryTest {
fun getActiveSliceDataTest() {
val page = SppLayer2.createSettingsPage()
val entryId = getUniqueEntryId("Layer2Entry1", page)
val sliceUri = Uri.Builder().appendSliceParams(page.buildRoute(), entryId).build()
val sliceUri = Uri.Builder().appendSpaParams(page.buildRoute(), entryId).build()
// build slice data first
val sliceData = sliceDataRepository.getOrBuildSliceData(sliceUri)

View File

@@ -43,14 +43,14 @@ class SliceUtilTest {
// valid slice uri
val dest = "myRoute"
val entryId = "myEntry"
val sliceUriWithoutParams = Uri.Builder().appendSliceParams(dest, entryId).build()
val sliceUriWithoutParams = Uri.Builder().appendSpaParams(dest, entryId).build()
assertThat(sliceUriWithoutParams.getEntryId()).isEqualTo(entryId)
assertThat(sliceUriWithoutParams.getDestination()).isEqualTo(dest)
assertThat(sliceUriWithoutParams.getRuntimeArguments().size()).isEqualTo(0)
assertThat(sliceUriWithoutParams.getSliceId()).isEqualTo("${entryId}_Bundle[{}]")
val sliceUriWithParams =
Uri.Builder().appendSliceParams(dest, entryId, bundleOf("p1" to "v1")).build()
Uri.Builder().appendSpaParams(dest, entryId, bundleOf("p1" to "v1")).build()
assertThat(sliceUriWithParams.getEntryId()).isEqualTo(entryId)
assertThat(sliceUriWithParams.getDestination()).isEqualTo(dest)
assertThat(sliceUriWithParams.getRuntimeArguments().size()).isEqualTo(1)
@@ -67,7 +67,7 @@ class SliceUtilTest {
// Valid Slice Uri
val dest = "myRoute"
val entryId = "myEntry"
val sliceUriWithoutParams = Uri.Builder().appendSliceParams(dest, entryId).build()
val sliceUriWithoutParams = Uri.Builder().appendSpaParams(dest, entryId).build()
val pendingIntent = sliceUriWithoutParams.createBroadcastPendingIntent()
assertThat(pendingIntent).isNotNull()
assertThat(pendingIntent!!.isBroadcast).isTrue()
@@ -87,7 +87,7 @@ class SliceUtilTest {
// Valid Slice Uri
val dest = "myRoute"
val entryId = "myEntry"
val sliceUri = Uri.Builder().appendSliceParams(dest, entryId).build()
val sliceUri = Uri.Builder().appendSpaParams(dest, entryId).build()
val pendingIntent = sliceUri.createBrowsePendingIntent()
assertThat(pendingIntent).isNotNull()
assertThat(pendingIntent!!.isActivity).isTrue()

View File

@@ -14,10 +14,12 @@
* limitations under the License.
*/
package com.android.settingslib.spa.framework.common
package com.android.settingslib.spa.tests.testutils
import android.os.Bundle
import androidx.navigation.NamedNavArgument
import com.android.settingslib.spa.framework.common.SettingsPage
import com.android.settingslib.spa.framework.common.toHashId
import com.android.settingslib.spa.framework.util.normalize
fun getUniquePageId(