diff --git a/Android.bp b/Android.bp index 4c472c8c411..8ca60b98b8f 100644 --- a/Android.bp +++ b/Android.bp @@ -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", diff --git a/protos/Android.bp b/protos/Android.bp index 560851a0862..4ab96a7a95d 100644 --- a/protos/Android.bp +++ b/protos/Android.bp @@ -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"], } diff --git a/protos/spa_search_landing.proto b/protos/spa_search_landing.proto new file mode 100644 index 00000000000..4305554470c --- /dev/null +++ b/protos/spa_search_landing.proto @@ -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; +} diff --git a/src/com/android/settings/spa/network/NetworkCellularGroupProvider.kt b/src/com/android/settings/spa/network/NetworkCellularGroupProvider.kt index b9a375cd081..f76bba45388 100644 --- a/src/com/android/settings/spa/network/NetworkCellularGroupProvider.kt +++ b/src/com/android/settings/spa/network/NetworkCellularGroupProvider.kt @@ -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 { if (!isPageSearchable(context)) return emptyList() return buildList { diff --git a/src/com/android/settings/spa/search/SearchablePage.kt b/src/com/android/settings/spa/search/SearchablePage.kt index 2364514ff83..f4a8795e4f4 100644 --- a/src/com/android/settings/spa/search/SearchablePage.kt +++ b/src/com/android/settings/spa/search/SearchablePage.kt @@ -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 } diff --git a/src/com/android/settings/spa/search/SpaSearchLandingActivity.kt b/src/com/android/settings/spa/search/SpaSearchLandingActivity.kt index 8c2bc37bfe5..fb2af93133e 100644 --- a/src/com/android/settings/spa/search/SpaSearchLandingActivity.kt +++ b/src/com/android/settings/spa/search/SpaSearchLandingActivity.kt @@ -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" + } } diff --git a/src/com/android/settings/spa/search/SpaSearchRepository.kt b/src/com/android/settings/spa/search/SpaSearchRepository.kt index d37c50c5f97..317c6208a40 100644 --- a/src/com/android/settings/spa/search/SpaSearchRepository.kt +++ b/src/com/android/settings/spa/search/SpaSearchRepository.kt @@ -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, ): SearchIndexableData { val searchIndexProvider = @@ -61,23 +65,36 @@ class SpaSearchRepository( override fun getDynamicRawDataToIndex( context: Context, enabled: Boolean, - ): List = - titlesProvider(context).map { title -> - createSearchIndexableRaw(context, title) + ): List { + val pageTitle = getPageTitleForSearch(context) + return titlesProvider(context).map { itemTitle -> + createSearchIndexableRaw(context, itemTitle, pageTitle) } + } override fun getNonIndexableKeys(context: Context): List = 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" diff --git a/tests/spa_unit/src/com/android/settings/spa/search/SpaSearchRepositoryTest.kt b/tests/spa_unit/src/com/android/settings/spa/search/SpaSearchRepositoryTest.kt index 911dfd2fc03..c38f22f129b 100644 --- a/tests/spa_unit/src/com/android/settings/spa/search/SpaSearchRepositoryTest.kt +++ b/tests/spa_unit/src/com/android/settings/spa/search/SpaSearchRepositoryTest.kt @@ -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(), 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" } }