Settings search for app data usage

Bug: 358238959
Flag: EXEMPT bug fix
Test: manual - search app data usage
Change-Id: Ie39a7f25b72f7b264f53329082fa34231c2aaa89
diff --git a/res/xml/mobile_network_settings.xml b/res/xml/mobile_network_settings.xml
index eb80ac8..825d72c 100644
--- a/res/xml/mobile_network_settings.xml
+++ b/res/xml/mobile_network_settings.xml
@@ -91,9 +91,11 @@
             settings:searchable="false"
             settings:controller="com.android.settings.network.telephony.RoamingPreferenceController"/>
 
+        <!-- Settings search is handled by DataUsageSearchItem. -->
         <Preference
             android:key="data_usage_summary"
             android:title="@string/app_cellular_data_usage"
+            settings:searchable="false"
             settings:controller="com.android.settings.network.telephony.DataUsagePreferenceController"/>
 
         <com.android.settings.datausage.BillingCyclePreference
diff --git a/src/com/android/settings/network/telephony/DataUsagePreferenceController.kt b/src/com/android/settings/network/telephony/DataUsagePreferenceController.kt
index d47a246..aa113b6 100644
--- a/src/com/android/settings/network/telephony/DataUsagePreferenceController.kt
+++ b/src/com/android/settings/network/telephony/DataUsagePreferenceController.kt
@@ -29,35 +29,32 @@
 import androidx.preference.Preference
 import androidx.preference.PreferenceScreen
 import com.android.settings.R
+import com.android.settings.core.BasePreferenceController
 import com.android.settings.datausage.DataUsageUtils
 import com.android.settings.datausage.lib.DataUsageFormatter.FormattedDataUsage
 import com.android.settings.datausage.lib.DataUsageLib
 import com.android.settings.datausage.lib.NetworkCycleDataRepository
 import com.android.settings.datausage.lib.NetworkStatsRepository.Companion.AllTimeRange
+import com.android.settings.network.telephony.MobileNetworkSettingsSearchIndex.MobileNetworkSettingsSearchItem
+import com.android.settings.network.telephony.MobileNetworkSettingsSearchIndex.MobileNetworkSettingsSearchResult
 import com.android.settingslib.spaprivileged.framework.compose.getPlaceholder
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.withContext
 
-/**
- * Preference controller for "Data usage"
- */
+/** Preference controller for "Data usage" */
 class DataUsagePreferenceController(context: Context, key: String) :
-    TelephonyBasePreferenceController(context, key) {
+    BasePreferenceController(context, key) {
 
+    private var subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID
     private lateinit var preference: Preference
     private var networkTemplate: NetworkTemplate? = null
 
     fun init(subId: Int) {
-        mSubId = subId
+        this.subId = subId
     }
 
-    override fun getAvailabilityStatus(subId: Int): Int = when {
-        SubscriptionManager.isValidSubscriptionId(subId) &&
-            DataUsageUtils.hasMobileData(mContext) -> AVAILABLE
-
-        else -> AVAILABLE_UNSEARCHABLE
-    }
+    override fun getAvailabilityStatus() = AVAILABLE
 
     override fun displayPreference(screen: PreferenceScreen) {
         super.displayPreference(screen)
@@ -75,11 +72,12 @@
 
     override fun handlePreferenceTreeClick(preference: Preference): Boolean {
         if (preference.key != preferenceKey || networkTemplate == null) return false
-        val intent = Intent(Settings.ACTION_MOBILE_DATA_USAGE).apply {
-            setPackage(mContext.packageName)
-            putExtra(Settings.EXTRA_NETWORK_TEMPLATE, networkTemplate)
-            putExtra(Settings.EXTRA_SUB_ID, mSubId)
-        }
+        val intent =
+            Intent(Settings.ACTION_MOBILE_DATA_USAGE).apply {
+                setPackage(mContext.packageName)
+                putExtra(Settings.EXTRA_NETWORK_TEMPLATE, networkTemplate)
+                putExtra(Settings.EXTRA_SUB_ID, subId)
+            }
         mContext.startActivity(intent)
         return true
     }
@@ -93,13 +91,10 @@
         preference.summary = summary?.displayText
     }
 
-    private fun getNetworkTemplate(): NetworkTemplate? = when {
-        SubscriptionManager.isValidSubscriptionId(mSubId) -> {
-            DataUsageLib.getMobileTemplate(mContext, mSubId)
-        }
-
-        else -> null
-    }
+    private fun getNetworkTemplate(): NetworkTemplate? =
+        if (SubscriptionManager.isValidSubscriptionId(subId)) {
+            DataUsageLib.getMobileTemplate(mContext, subId)
+        } else null
 
     @VisibleForTesting
     fun createNetworkCycleDataRepository(): NetworkCycleDataRepository? =
@@ -118,4 +113,16 @@
         val allTimeUsage = repository.queryUsage(AllTimeRange)
         return allTimeUsage.getDataUsedString(mContext) to (allTimeUsage.usage > 0)
     }
+
+    companion object {
+        class DataUsageSearchItem(private val context: Context) : MobileNetworkSettingsSearchItem {
+            override fun getSearchResult(subId: Int): MobileNetworkSettingsSearchResult? {
+                if (!DataUsageUtils.hasMobileData(context)) return null
+                return MobileNetworkSettingsSearchResult(
+                    key = "data_usage_summary",
+                    title = context.getString(R.string.app_cellular_data_usage),
+                )
+            }
+        }
+    }
 }
diff --git a/src/com/android/settings/network/telephony/MobileNetworkSettingsSearchIndex.kt b/src/com/android/settings/network/telephony/MobileNetworkSettingsSearchIndex.kt
index 58661f0..55cb1fa 100644
--- a/src/com/android/settings/network/telephony/MobileNetworkSettingsSearchIndex.kt
+++ b/src/com/android/settings/network/telephony/MobileNetworkSettingsSearchIndex.kt
@@ -21,6 +21,7 @@
 import android.telephony.SubscriptionInfo
 import com.android.settings.R
 import com.android.settings.network.SubscriptionUtil
+import com.android.settings.network.telephony.DataUsagePreferenceController.Companion.DataUsageSearchItem
 import com.android.settings.network.telephony.MmsMessagePreferenceController.Companion.MmsMessageSearchItem
 import com.android.settings.network.telephony.NrAdvancedCallingPreferenceController.Companion.NrAdvancedCallingSearchItem
 import com.android.settings.network.telephony.RoamingPreferenceController.Companion.RoamingSearchItem
@@ -114,6 +115,7 @@
 
         fun createSearchItems(context: Context): List<MobileNetworkSettingsSearchItem> =
             listOf(
+                DataUsageSearchItem(context),
                 MmsMessageSearchItem(context),
                 NrAdvancedCallingSearchItem(context),
                 PreferredNetworkModeSearchItem(context),
diff --git a/tests/spa_unit/src/com/android/settings/network/telephony/DataUsagePreferenceControllerTest.kt b/tests/spa_unit/src/com/android/settings/network/telephony/DataUsagePreferenceControllerTest.kt
index 7124b6a..f4974e9 100644
--- a/tests/spa_unit/src/com/android/settings/network/telephony/DataUsagePreferenceControllerTest.kt
+++ b/tests/spa_unit/src/com/android/settings/network/telephony/DataUsagePreferenceControllerTest.kt
@@ -29,7 +29,6 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import com.android.dx.mockito.inline.extended.ExtendedMockito
 import com.android.settings.core.BasePreferenceController.AVAILABLE
-import com.android.settings.core.BasePreferenceController.AVAILABLE_UNSEARCHABLE
 import com.android.settings.datausage.DataUsageUtils
 import com.android.settings.datausage.lib.DataUsageLib
 import com.android.settings.datausage.lib.NetworkCycleDataRepository
@@ -77,7 +76,6 @@
     @Before
     fun setUp() {
         mockSession = ExtendedMockito.mockitoSession()
-            .initMocks(this)
             .spyStatic(DataUsageUtils::class.java)
             .spyStatic(DataUsageLib::class.java)
             .strictness(Strictness.LENIENT)
@@ -101,19 +99,11 @@
     }
 
     @Test
-    fun getAvailabilityStatus_validSubId_returnAvailable() {
+    fun getAvailabilityStatus_returnAvailable() {
         assertThat(controller.availabilityStatus).isEqualTo(AVAILABLE)
     }
 
     @Test
-    fun getAvailabilityStatus_invalidSubId_returnUnsearchable() {
-        val availabilityStatus =
-            controller.getAvailabilityStatus(SubscriptionManager.INVALID_SUBSCRIPTION_ID)
-
-        assertThat(availabilityStatus).isEqualTo(AVAILABLE_UNSEARCHABLE)
-    }
-
-    @Test
     fun handlePreferenceTreeClick_startActivity() = runBlocking {
         val usageData = NetworkUsageData(START_TIME, END_TIME, 1L)
         repository.stub {