Show category when search "Mobile data"

The displayed category is "SIMs".

Bug: 346776183
Flag: EXEMPT bug fix
Test: manual - search "Mobile data"
Test: unit test
Change-Id: If3c395281e96603193e7476a9e76d1f9e9213531
This commit is contained in:
Chaohui Wang
2024-07-26 14:51:33 +08:00
parent 50a18d9e85
commit 7477f4ea9a
8 changed files with 93 additions and 56 deletions

View File

@@ -82,12 +82,10 @@ android_library {
"android.hardware.dumpstate-V1-java",
"android.hardware.dumpstate-V1.0-java",
"android.hardware.dumpstate-V1.1-java",
"android.view.accessibility.flags-aconfig-java",
"com_android_server_accessibility_flags_lib",
"net-utils-framework-common",
"notification_flags_lib",
"securebox",
"android.os.flags-aconfig-java",
"//frameworks/libs/systemui:com_android_systemui_shared_flags_lib",
"WindowManager-Shell-shared-desktopMode",
@@ -103,12 +101,9 @@ android_library {
"contextualcards",
"development_settings_flag_lib",
"factory_reset_flags_lib",
"fuelgauge-log-protos-lite",
"settings-protos-lite",
"fuelgauge-protos-lite",
"settings-contextual-card-protos-lite",
"settings-log-bridge-protos-lite",
"settings-logtags",
"settings-telephony-protos-lite",
"statslog-settings",
"telephony_flags_core_java_lib",
"setupdesign-lottie-loading-layout",

View File

@@ -1,44 +1,12 @@
package {
default_team: "trendy_team_android_settings_app",
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "packages_apps_Settings_license"
// to get the below license kinds:
// SPDX-license-identifier-Apache-2.0
default_applicable_licenses: ["packages_apps_Settings_license"],
}
java_library_static {
name: "settings-contextual-card-protos-lite",
host_supported: true,
proto: {
type: "lite",
},
srcs: ["contextual_card_list.proto"],
}
java_library_static {
name: "settings-log-bridge-protos-lite",
host_supported: true,
proto: {
type: "lite",
},
srcs: ["settings_log_bridge.proto"],
}
java_library_static {
name: "settings-telephony-protos-lite",
host_supported: true,
proto: {
type: "lite",
},
srcs: ["network_mode_choices.proto"],
}
java_library {
name: "fuelgauge-log-protos-lite",
name: "settings-protos-lite",
proto: {
type: "lite",
},
srcs: ["fuelgauge_log.proto"],
srcs: ["*.proto"],
}

View File

@@ -0,0 +1,14 @@
syntax = "proto2";
package com.android.settings.spa;
message SpaSearchLandingKey {
oneof page {
SpaSearchLandingSpaPage spa_page = 1;
}
}
message SpaSearchLandingSpaPage {
/** The destination of SPA page. */
optional string destination = 1;
}

View File

@@ -197,6 +197,9 @@ open class NetworkCellularGroupProvider : SettingsPageProvider, SearchablePage {
// Do nothing
}
override fun getPageTitleForSearch(context: Context): String =
context.getString(R.string.provider_network_settings_title)
override fun getSearchableTitles(context: Context): List<String> {
if (!isPageSearchable(context)) return emptyList()
return buildList {

View File

@@ -20,6 +20,9 @@ import android.content.Context
interface SearchablePage {
/** Gets the searchable titles at the current moment. */
/** Gets the title of the page. */
fun getPageTitleForSearch(context: Context): String = ""
/** Gets the titles of the searchable items at the current moment. */
fun getSearchableTitles(context: Context): List<String>
}

View File

@@ -18,25 +18,45 @@ package com.android.settings.spa.search
import android.app.Activity
import android.os.Bundle
import android.util.Log
import com.android.settings.SettingsActivity.EXTRA_FRAGMENT_ARG_KEY
import com.android.settings.overlay.FeatureFactory.Companion.featureFactory
import com.android.settings.password.PasswordUtils
import com.android.settings.spa.SpaDestination
import com.android.settings.spa.SpaSearchLanding
import com.google.protobuf.ByteString
import com.google.protobuf.InvalidProtocolBufferException
class SpaSearchLandingActivity : Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (!isValidCall()) return
val destination = intent.getStringExtra(EXTRA_FRAGMENT_ARG_KEY)
if (destination.isNullOrBlank()) return
val keyString = intent.getStringExtra(EXTRA_FRAGMENT_ARG_KEY)
val key =
try {
SpaSearchLanding.SpaSearchLandingKey.parseFrom(ByteString.copyFromUtf8(keyString))
} catch (e: InvalidProtocolBufferException) {
Log.w(TAG, "arg key ($keyString) invalid", e)
finish()
return
}
SpaDestination(destination = destination, highlightMenuKey = null)
.startFromExportedActivity(this)
if (key.hasSpaPage()) {
val destination = key.spaPage.destination
if (destination.isNotEmpty()) {
SpaDestination(destination = destination, highlightMenuKey = null)
.startFromExportedActivity(this)
}
}
finish()
}
private fun isValidCall() =
PasswordUtils.getCallingAppPackageName(activityToken) ==
featureFactory.searchFeatureProvider.getSettingsIntelligencePkgName(this)
private companion object {
private const val TAG = "SpaSearchLandingActivity"
}
}

View File

@@ -20,6 +20,8 @@ import android.content.Context
import android.provider.SearchIndexableResource
import android.util.Log
import androidx.annotation.VisibleForTesting
import com.android.settings.spa.SpaSearchLanding.SpaSearchLandingKey
import com.android.settings.spa.SpaSearchLanding.SpaSearchLandingSpaPage
import com.android.settingslib.search.Indexable
import com.android.settingslib.search.SearchIndexableData
import com.android.settingslib.search.SearchIndexableRaw
@@ -34,7 +36,8 @@ class SpaSearchRepository(
Log.d(TAG, "getSearchIndexableDataList")
return spaEnvironment.pageProviderRepository.value.getAllProviders().mapNotNull { page ->
if (page is SearchablePage) {
page.createSearchIndexableData(page::getSearchableTitles)
page.createSearchIndexableData(
page::getPageTitleForSearch, page::getSearchableTitles)
} else null
}
}
@@ -44,6 +47,7 @@ class SpaSearchRepository(
@VisibleForTesting
fun SettingsPageProvider.createSearchIndexableData(
getPageTitleForSearch: (context: Context) -> String,
titlesProvider: (context: Context) -> List<String>,
): SearchIndexableData {
val searchIndexProvider =
@@ -61,23 +65,36 @@ class SpaSearchRepository(
override fun getDynamicRawDataToIndex(
context: Context,
enabled: Boolean,
): List<SearchIndexableRaw> =
titlesProvider(context).map { title ->
createSearchIndexableRaw(context, title)
): List<SearchIndexableRaw> {
val pageTitle = getPageTitleForSearch(context)
return titlesProvider(context).map { itemTitle ->
createSearchIndexableRaw(context, itemTitle, pageTitle)
}
}
override fun getNonIndexableKeys(context: Context): List<String> = emptyList()
}
return SearchIndexableData(this::class.java, searchIndexProvider)
}
private fun SettingsPageProvider.createSearchIndexableRaw(context: Context, title: String) =
private fun SettingsPageProvider.createSearchIndexableRaw(
context: Context,
itemTitle: String,
pageTitle: String,
) =
SearchIndexableRaw(context).apply {
key = name
this.title = title
key =
SpaSearchLandingKey.newBuilder()
.setSpaPage(SpaSearchLandingSpaPage.newBuilder().setDestination(name))
.build()
.toByteString()
.toStringUtf8()
title = itemTitle
intentAction = SEARCH_LANDING_ACTION
intentTargetClass = SpaSearchLandingActivity::class.qualifiedName
packageName = context.packageName
className = SpaSearchLandingActivity::class.qualifiedName
className = this@createSearchIndexableRaw::class.java.name
screenTitle = pageTitle
}
private const val SEARCH_LANDING_ACTION = "android.settings.SPA_SEARCH_LANDING"

View File

@@ -18,9 +18,12 @@ package com.android.settings.spa.search
import android.content.Context
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.android.settings.spa.SpaSearchLanding.SpaSearchLandingKey
import com.android.settings.spa.SpaSearchLanding.SpaSearchLandingSpaPage
import com.android.settings.spa.search.SpaSearchRepository.Companion.createSearchIndexableData
import com.android.settingslib.spa.framework.common.SettingsPageProvider
import com.google.common.truth.Truth.assertThat
import com.google.protobuf.ByteString
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.kotlin.mock
@@ -35,17 +38,31 @@ class SpaSearchRepositoryTest {
override val name = PAGE_NAME
}
val searchIndexableData = pageProvider.createSearchIndexableData { listOf(TITLE) }
val searchIndexableData =
pageProvider.createSearchIndexableData({ PAGE_TITLE }) { listOf(ITEM_TITLE) }
val dynamicRawDataToIndex =
searchIndexableData.searchIndexProvider.getDynamicRawDataToIndex(mock<Context>(), true)
assertThat(searchIndexableData.targetClass).isEqualTo(pageProvider::class.java)
assertThat(dynamicRawDataToIndex).hasSize(1)
assertThat(dynamicRawDataToIndex[0].title).isEqualTo(TITLE)
val rawData = dynamicRawDataToIndex[0]
val key = SpaSearchLandingKey.parseFrom(ByteString.copyFromUtf8(rawData.key))
assertThat(key)
.isEqualTo(
SpaSearchLandingKey.newBuilder()
.setSpaPage(SpaSearchLandingSpaPage.newBuilder().setDestination(PAGE_NAME))
.build())
assertThat(rawData.title).isEqualTo(ITEM_TITLE)
assertThat(rawData.intentAction).isEqualTo("android.settings.SPA_SEARCH_LANDING")
assertThat(rawData.intentTargetClass)
.isEqualTo(SpaSearchLandingActivity::class.qualifiedName)
assertThat(rawData.className).isEqualTo(pageProvider::class.java.name)
assertThat(rawData.screenTitle).isEqualTo(PAGE_TITLE)
}
private companion object {
const val PAGE_NAME = "PageName"
const val TITLE = "Title"
const val PAGE_TITLE = "Page Title"
const val ITEM_TITLE = "Item Title"
}
}