From 387753c0050cca382cac2ae698bb849f0c406cfd Mon Sep 17 00:00:00 2001 From: Jacky Wang Date: Sun, 8 Dec 2024 21:08:38 +0800 Subject: [PATCH] [Catalyst] Refine DataSaverMainSwitchPreference Export datastore for preference state monitoring. Bug: 368359883 Flag: com.android.settings.flags.catalyst Test: devtool Change-Id: Ie6b001cdd6a8d27f9cb16d563852ad88b7366916 --- .../DataSaverMainSwitchPreference.kt | 40 ++++++++----------- .../settings/datausage/DataSaverScreen.kt | 32 +++++++++------ .../settings/datausage/DataSaverScreenTest.kt | 5 ++- 3 files changed, 40 insertions(+), 37 deletions(-) diff --git a/src/com/android/settings/datausage/DataSaverMainSwitchPreference.kt b/src/com/android/settings/datausage/DataSaverMainSwitchPreference.kt index e4e38d42530..23cfadce3d0 100644 --- a/src/com/android/settings/datausage/DataSaverMainSwitchPreference.kt +++ b/src/com/android/settings/datausage/DataSaverMainSwitchPreference.kt @@ -19,18 +19,14 @@ package com.android.settings.datausage import android.content.Context import com.android.settings.R import com.android.settings.widget.MainSwitchBarMetadata +import com.android.settingslib.datastore.AbstractKeyedDataObservable +import com.android.settingslib.datastore.DataChangeReason import com.android.settingslib.datastore.KeyValueStore -import com.android.settingslib.datastore.NoOpKeyedObservable -import com.android.settingslib.metadata.PreferenceLifecycleContext import com.android.settingslib.metadata.PreferenceLifecycleProvider import com.android.settingslib.metadata.ReadWritePermit import com.android.settingslib.metadata.SensitivityLevel -class DataSaverMainSwitchPreference(context: Context) : - MainSwitchBarMetadata, PreferenceLifecycleProvider { - - private val dataSaverBackend = DataSaverBackend(context) - private var dataSaverBackendListener: DataSaverBackend.Listener? = null +class DataSaverMainSwitchPreference : MainSwitchBarMetadata, PreferenceLifecycleProvider { override val key get() = KEY @@ -38,7 +34,7 @@ class DataSaverMainSwitchPreference(context: Context) : override val title get() = R.string.data_saver_switch_title - override fun storage(context: Context): KeyValueStore = DataSaverStore(dataSaverBackend) + override fun storage(context: Context) = createDataStore(context) override fun getReadPermit(context: Context, myUid: Int, callingUid: Int) = ReadWritePermit.ALLOW @@ -49,24 +45,11 @@ class DataSaverMainSwitchPreference(context: Context) : override val sensitivityLevel get() = SensitivityLevel.NO_SENSITIVITY - override fun onStart(context: PreferenceLifecycleContext) { - val listener = DataSaverBackend.Listener { context.notifyPreferenceChange(KEY) } - dataSaverBackendListener = listener - dataSaverBackend.addListener(listener) - } - - override fun onStop(context: PreferenceLifecycleContext) { - dataSaverBackendListener?.let { - dataSaverBackend.remListener(it) - dataSaverBackendListener = null - } - } - @Suppress("UNCHECKED_CAST") private class DataSaverStore(private val dataSaverBackend: DataSaverBackend) : - NoOpKeyedObservable(), KeyValueStore { + AbstractKeyedDataObservable(), KeyValueStore, DataSaverBackend.Listener { - override fun contains(key: String) = true // just assume the datastore contains the value + override fun contains(key: String) = key == KEY override fun getValue(key: String, valueType: Class): T? = dataSaverBackend.isDataSaverEnabled as T? @@ -74,9 +57,20 @@ class DataSaverMainSwitchPreference(context: Context) : override fun setValue(key: String, valueType: Class, value: T?) { dataSaverBackend.isDataSaverEnabled = value as Boolean } + + override fun onFirstObserverAdded() = dataSaverBackend.addListener(this) + + override fun onLastObserverRemoved() = dataSaverBackend.remListener(this) + + override fun onDataSaverChanged(isDataSaving: Boolean) = + notifyChange(KEY, DataChangeReason.UPDATE) } companion object { const val KEY = "use_data_saver" + + /** Creates [KeyValueStore] for data saver preference. */ + fun createDataStore(context: Context): KeyValueStore = + DataSaverStore(DataSaverBackend(context)) } } diff --git a/src/com/android/settings/datausage/DataSaverScreen.kt b/src/com/android/settings/datausage/DataSaverScreen.kt index 2e806432833..fd4441fbbe2 100644 --- a/src/com/android/settings/datausage/DataSaverScreen.kt +++ b/src/com/android/settings/datausage/DataSaverScreen.kt @@ -19,24 +19,30 @@ package com.android.settings.datausage import android.content.Context import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID import com.android.settings.R +import com.android.settings.Settings.DataSaverSummaryActivity import com.android.settings.flags.Flags +import com.android.settings.utils.makeLaunchIntent +import com.android.settingslib.datastore.HandlerExecutor +import com.android.settingslib.datastore.KeyedObserver import com.android.settingslib.metadata.PreferenceAvailabilityProvider import com.android.settingslib.metadata.PreferenceLifecycleContext import com.android.settingslib.metadata.PreferenceLifecycleProvider +import com.android.settingslib.metadata.PreferenceMetadata import com.android.settingslib.metadata.PreferenceSummaryProvider import com.android.settingslib.metadata.ProvidePreferenceScreen import com.android.settingslib.metadata.preferenceHierarchy import com.android.settingslib.preference.PreferenceScreenCreator +import com.android.settings.datausage.DataSaverMainSwitchPreference.Companion.KEY as DATA_SAVER_KEY @ProvidePreferenceScreen -class DataSaverScreen : +class DataSaverScreen(context: Context) : PreferenceScreenCreator, PreferenceAvailabilityProvider, PreferenceSummaryProvider, PreferenceLifecycleProvider { - private var dataSaverBackend: DataSaverBackend? = null - private var dataSaverBackendListener: DataSaverBackend.Listener? = null + private val dataSaverStore = DataSaverMainSwitchPreference.createDataStore(context) + private lateinit var keyedObserver: KeyedObserver override val key get() = KEY @@ -53,7 +59,7 @@ class DataSaverScreen : override fun getSummary(context: Context): CharSequence? = when { - DataSaverBackend(context).isDataSaverEnabled -> + dataSaverStore.getBoolean(DATA_SAVER_KEY) == true -> context.getString(R.string.data_saver_on) else -> context.getString(R.string.data_saver_off) } @@ -65,21 +71,21 @@ class DataSaverScreen : override fun fragmentClass() = DataSaverSummary::class.java + override fun getLaunchIntent(context: Context, metadata: PreferenceMetadata?) = + makeLaunchIntent(context, DataSaverSummaryActivity::class.java, metadata?.key) + override fun getPreferenceHierarchy(context: Context) = - preferenceHierarchy(this) { +DataSaverMainSwitchPreference(context) } + preferenceHierarchy(this) { +DataSaverMainSwitchPreference() } override fun hasCompleteHierarchy() = false - override fun onStart(context: PreferenceLifecycleContext) { - val listener = DataSaverBackend.Listener { context.notifyPreferenceChange(KEY) } - dataSaverBackendListener = listener - dataSaverBackend = DataSaverBackend(context).apply { addListener(listener) } + override fun onCreate(context: PreferenceLifecycleContext) { + keyedObserver = KeyedObserver { _, _ -> context.notifyPreferenceChange(KEY) } + dataSaverStore.addObserver(DATA_SAVER_KEY, keyedObserver, HandlerExecutor.main) } - override fun onStop(context: PreferenceLifecycleContext) { - dataSaverBackend?.remListener(dataSaverBackendListener) - dataSaverBackend = null - dataSaverBackendListener = null + override fun onDestroy(context: PreferenceLifecycleContext) { + dataSaverStore.removeObserver(DATA_SAVER_KEY, keyedObserver) } companion object { diff --git a/tests/robotests/src/com/android/settings/datausage/DataSaverScreenTest.kt b/tests/robotests/src/com/android/settings/datausage/DataSaverScreenTest.kt index 08af4c0e862..24e8213e566 100644 --- a/tests/robotests/src/com/android/settings/datausage/DataSaverScreenTest.kt +++ b/tests/robotests/src/com/android/settings/datausage/DataSaverScreenTest.kt @@ -16,13 +16,16 @@ package com.android.settings.datausage +import androidx.test.core.app.ApplicationProvider import com.android.settings.flags.Flags import com.android.settingslib.preference.CatalystScreenTestCase import com.google.common.truth.Truth.assertThat import org.junit.Test class DataSaverScreenTest : CatalystScreenTestCase() { - override val preferenceScreenCreator = DataSaverScreen() + override val preferenceScreenCreator = + DataSaverScreen(ApplicationProvider.getApplicationContext()) + override val flagName get() = Flags.FLAG_CATALYST_RESTRICT_BACKGROUND_PARENT_ENTRY