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

Commit 01104a5b authored by Jacky Wang's avatar Jacky Wang
Browse files

[Catalyst] Provide MetricsCategory for screen metadata

Bug: 389886085
Bug: 409940414
Flag: EXEMPT framework
Test: statsd_testdrive
Change-Id: I1120d0a4c148b8a6369ea5e6e552e090fe6fc909
parent 1851610e
Loading
Loading
Loading
Loading
+12 −3
Original line number Diff line number Diff line
@@ -18,6 +18,8 @@ package com.android.settings

import android.content.Intent
import android.os.Bundle
import com.android.settings.dashboard.DashboardFragment
import com.android.settingslib.core.instrumentation.Instrumentable
import com.android.settingslib.metadata.EXTRA_BINDING_SCREEN_KEY
import com.android.settingslib.preference.PreferenceFragment

@@ -45,11 +47,18 @@ constructor(
/**
 * Fragment to load catalyst preference screen.
 *
 * `PreferenceFragment` class is not used as it does not support highlighting specific preference.
 * Use [DashboardFragment] as base class instead of [PreferenceFragment] to support injection and
 * highlighting specific preference.
 */
class CatalystFragment : SettingsPreferenceFragment() {
class CatalystFragment : DashboardFragment() {

    override fun getMetricsCategory() = 0
    override fun getPreferenceScreenResId() = 0

    override fun getLogTag(): String = javaClass.simpleName

    override fun getMetricsCategory() =
        context?.let { getPreferenceScreenCreator(it) as? Instrumentable }?.metricsCategory
            ?: METRICS_CATEGORY_UNKNOWN

    override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
        preferenceScreen = createPreferenceScreen()
+23 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 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.settings.core

import com.android.settingslib.core.instrumentation.Instrumentable
import com.android.settingslib.preference.PreferenceScreenCreator

/** Mixin for settings preference screen. */
interface PreferenceScreenMixin : PreferenceScreenCreator, Instrumentable
+10 −6
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.settings.metrics

import android.content.Context
import com.android.settings.overlay.FeatureFactory
import com.android.settingslib.core.instrumentation.Instrumentable
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider
import com.android.settingslib.metadata.PreferenceMetadata
import com.android.settingslib.metadata.PreferenceScreenMetadata
@@ -37,11 +38,14 @@ constructor(
        preference: PreferenceMetadata,
        value: Any?,
    ) {
        if (preference !is PreferenceActionMetricsProvider) return
        val metricsCategory =
            (screen as? Instrumentable)?.metricsCategory ?: Instrumentable.METRICS_CATEGORY_UNKNOWN
        val intValue =
            when (value) {
            is Boolean ->
                metricsFeatureProvider.action(context, preference.preferenceActionMetrics, value)
            else -> {}
                is Boolean -> if (value == true) 1 else 0
                is Int -> value
                else -> return
            }
        metricsFeatureProvider.changed(metricsCategory, preference.key, intValue)
    }
}
+17 −10
Original line number Diff line number Diff line
@@ -16,17 +16,18 @@

package com.android.settings.network

import android.app.settings.SettingsEnums.ACTION_AIRPLANE_TOGGLE
import android.app.settings.SettingsEnums.SETTINGS_NETWORK_CATEGORY
import android.content.Context
import android.content.ContextWrapper
import android.content.pm.PackageManager
import android.content.pm.PackageManager.FEATURE_LEANBACK
import android.content.res.Resources
import android.provider.Settings
import android.provider.Settings.Global.AIRPLANE_MODE_ON
import android.telephony.TelephonyManager
import androidx.preference.SwitchPreferenceCompat
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.android.settings.core.PreferenceScreenMixin
import com.android.settings.testutils.MetricsRule
import com.android.settingslib.datastore.SettingsGlobalStore
import com.android.settingslib.preference.createAndBindWidget
@@ -46,7 +47,11 @@ class AirplaneModePreferenceTest {

    private val mockResources = mock<Resources>()
    private val mockPackageManager = mock<PackageManager>()
    private var mockTelephonyManager = mock<TelephonyManager>()
    private val mockTelephonyManager = mock<TelephonyManager>()
    private val mockScreenMetadata =
        mock<PreferenceScreenMixin> {
            on { getMetricsCategory() } doReturn SETTINGS_NETWORK_CATEGORY
        }

    private val context = ApplicationProvider.getApplicationContext<Context>()
    private val contextWrapper =
@@ -90,7 +95,7 @@ class AirplaneModePreferenceTest {

    @Test
    fun getValue_defaultOn_returnOn() {
        SettingsGlobalStore.get(context).setInt(Settings.Global.AIRPLANE_MODE_ON, 1)
        SettingsGlobalStore.get(context).setInt(AIRPLANE_MODE_ON, 1)

        val getValue =
            airplaneModePreference.storage(context).getBoolean(AirplaneModePreference.KEY)
@@ -100,7 +105,7 @@ class AirplaneModePreferenceTest {

    @Test
    fun getValue_defaultOff_returnOff() {
        SettingsGlobalStore.get(context).setInt(Settings.Global.AIRPLANE_MODE_ON, 0)
        SettingsGlobalStore.get(context).setInt(AIRPLANE_MODE_ON, 0)

        val getValue =
            airplaneModePreference.storage(context).getBoolean(AirplaneModePreference.KEY)
@@ -110,24 +115,26 @@ class AirplaneModePreferenceTest {

    @Test
    fun performClick_defaultOn_checkedIsFalse() {
        SettingsGlobalStore.get(context).setInt(Settings.Global.AIRPLANE_MODE_ON, 1)
        SettingsGlobalStore.get(context).setInt(AIRPLANE_MODE_ON, 1)

        val preference = getSwitchPreference().apply { performClick() }

        assertThat(preference.isChecked).isFalse()
        verify(metricsRule.metricsFeatureProvider).action(context, ACTION_AIRPLANE_TOGGLE, false)
        verify(metricsRule.metricsFeatureProvider)
            .changed(SETTINGS_NETWORK_CATEGORY, AIRPLANE_MODE_ON, 0)
    }

    @Test
    fun performClick_defaultOff_checkedIsTrue() {
        SettingsGlobalStore.get(context).setInt(Settings.Global.AIRPLANE_MODE_ON, 0)
        SettingsGlobalStore.get(context).setInt(AIRPLANE_MODE_ON, 0)

        val preference = getSwitchPreference().apply { performClick() }

        assertThat(preference.isChecked).isTrue()
        verify(metricsRule.metricsFeatureProvider).action(context, ACTION_AIRPLANE_TOGGLE, true)
        verify(metricsRule.metricsFeatureProvider)
            .changed(SETTINGS_NETWORK_CATEGORY, AIRPLANE_MODE_ON, 1)
    }

    private fun getSwitchPreference(): SwitchPreferenceCompat =
        airplaneModePreference.createAndBindWidget(context)
        airplaneModePreference.createAndBindWidget(context, null, mockScreenMetadata)
}