From a794e01d458380d88c6dd796a726c17e6cd5ee32 Mon Sep 17 00:00:00 2001 From: Fan Wu Date: Thu, 14 Nov 2024 01:36:43 +0000 Subject: [PATCH] Revert "Revert "Migrate Battery percentage preference into catal..." Revert submission 30375632-revert-30294757-catalyst_battery_percentage-RPJNJOPEZI Reason for revert: the failures is part of the robolectric issue b/378822459. Tested locally that the change is not breaking ClockworkSetupWizardRoboTests. Reverted changes: /q/submissionid:30375632-revert-30294757-catalyst_battery_percentage-RPJNJOPEZI Change-Id: I2210002924650cb54c55a41be25d97a3997c065e --- ...BatteryPercentagePreferenceController.java | 4 +- .../BatteryPercentageSwitchPreference.kt | 95 +++++++++++++ .../batteryusage/PowerUsageSummaryScreen.kt | 12 +- ...eryPercentagePreferenceControllerTest.java | 4 +- .../BatteryPercentageSwitchPreferenceTest.kt | 130 ++++++++++++++++++ 5 files changed, 237 insertions(+), 8 deletions(-) create mode 100644 src/com/android/settings/display/BatteryPercentageSwitchPreference.kt create mode 100644 tests/robotests/src/com/android/settings/display/BatteryPercentageSwitchPreferenceTest.kt diff --git a/src/com/android/settings/display/BatteryPercentagePreferenceController.java b/src/com/android/settings/display/BatteryPercentagePreferenceController.java index a7113b3d490..b859c78af5f 100644 --- a/src/com/android/settings/display/BatteryPercentagePreferenceController.java +++ b/src/com/android/settings/display/BatteryPercentagePreferenceController.java @@ -35,6 +35,7 @@ import com.android.settings.overlay.FeatureFactory; * A controller to manage the switch for showing battery percentage in the status bar. */ +// LINT.IfChange public class BatteryPercentagePreferenceController extends BasePreferenceController implements PreferenceControllerMixin, Preference.OnPreferenceChangeListener { @@ -69,7 +70,7 @@ public class BatteryPercentagePreferenceController extends BasePreferenceControl int setting = Settings.System.getInt(mContext.getContentResolver(), SHOW_BATTERY_PERCENT, mContext.getResources().getBoolean( - R.bool.config_defaultBatteryPercentageSetting) ? 1 : 0); + R.bool.config_defaultBatteryPercentageSetting) ? 1 : 0); ((TwoStatePreference) preference).setChecked(setting == 1); } @@ -84,3 +85,4 @@ public class BatteryPercentagePreferenceController extends BasePreferenceControl return true; } } +// LINT.ThenChange(BatteryPercentageSwitchPreference.kt) diff --git a/src/com/android/settings/display/BatteryPercentageSwitchPreference.kt b/src/com/android/settings/display/BatteryPercentageSwitchPreference.kt new file mode 100644 index 00000000000..8571cf18c85 --- /dev/null +++ b/src/com/android/settings/display/BatteryPercentageSwitchPreference.kt @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2024 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.display + +import android.app.settings.SettingsEnums +import android.content.Context +import android.provider.Settings +import androidx.preference.Preference +import com.android.settings.R +import com.android.settings.Utils +import com.android.settings.overlay.FeatureFactory.Companion.featureFactory +import com.android.settingslib.datastore.KeyValueStore +import com.android.settingslib.datastore.KeyedObservableDelegate +import com.android.settingslib.datastore.SettingsStore +import com.android.settingslib.datastore.SettingsSystemStore +import com.android.settingslib.metadata.PreferenceAvailabilityProvider +import com.android.settingslib.metadata.PreferenceMetadata +import com.android.settingslib.metadata.ReadWritePermit +import com.android.settingslib.metadata.SwitchPreference +import com.android.settingslib.preference.SwitchPreferenceBinding + +// LINT.IfChange +class BatteryPercentageSwitchPreference : + SwitchPreference(KEY, R.string.battery_percentage, R.string.battery_percentage_description), + SwitchPreferenceBinding, + PreferenceAvailabilityProvider, + Preference.OnPreferenceChangeListener { + + override fun storage(context: Context): KeyValueStore = + BatteryPercentageStorage(context, SettingsSystemStore.get(context)) + + override fun isAvailable(context: Context): Boolean = + Utils.isBatteryPresent(context) && + context.resources.getBoolean( + com.android.internal.R.bool.config_battery_percentage_setting_available + ) + + override fun getWritePermit(context: Context, value: Boolean?, myUid: Int, callingUid: Int) = + ReadWritePermit.ALLOW + + override fun bind(preference: Preference, metadata: PreferenceMetadata) { + super.bind(preference, metadata) + preference.onPreferenceChangeListener = this + } + + override fun onPreferenceChange(preference: Preference, newValue: Any?): Boolean { + val showPercentage = newValue as Boolean + + featureFactory.metricsFeatureProvider.action( + preference.context, + SettingsEnums.OPEN_BATTERY_PERCENTAGE, + showPercentage, + ) + return true + } + + @Suppress("UNCHECKED_CAST") + private class BatteryPercentageStorage( + private val context: Context, + private val settingsStore: SettingsStore, + ) : KeyedObservableDelegate(settingsStore), KeyValueStore { + + override fun contains(key: String) = settingsStore.contains(KEY) + + override fun getValue(key: String, valueType: Class) = + (settingsStore.getBoolean(key) ?: getDefaultValue(key, valueType)) as T + + override fun setValue(key: String, valueType: Class, value: T?) { + settingsStore.setBoolean(key, value as Boolean) + } + + override fun getDefaultValue(key: String, valueType: Class) = + context.resources.getBoolean( + com.android.internal.R.bool.config_defaultBatteryPercentageSetting + ) as T + } + + companion object { + const val KEY = Settings.System.SHOW_BATTERY_PERCENT + } +} +// LINT.ThenChange(BatteryPercentagePreferenceController.java) diff --git a/src/com/android/settings/fuelgauge/batteryusage/PowerUsageSummaryScreen.kt b/src/com/android/settings/fuelgauge/batteryusage/PowerUsageSummaryScreen.kt index 229e3084081..b397bf3ded6 100644 --- a/src/com/android/settings/fuelgauge/batteryusage/PowerUsageSummaryScreen.kt +++ b/src/com/android/settings/fuelgauge/batteryusage/PowerUsageSummaryScreen.kt @@ -17,6 +17,7 @@ package com.android.settings.fuelgauge.batteryusage import android.content.Context import com.android.settings.R +import com.android.settings.display.BatteryPercentageSwitchPreference import com.android.settings.flags.Flags import com.android.settingslib.metadata.PreferenceAvailabilityProvider import com.android.settingslib.metadata.PreferenceIconProvider @@ -25,9 +26,8 @@ import com.android.settingslib.metadata.preferenceHierarchy import com.android.settingslib.preference.PreferenceScreenCreator @ProvidePreferenceScreen -class PowerUsageSummaryScreen : PreferenceScreenCreator, - PreferenceAvailabilityProvider, - PreferenceIconProvider { +class PowerUsageSummaryScreen : + PreferenceScreenCreator, PreferenceAvailabilityProvider, PreferenceIconProvider { override val key: String get() = KEY @@ -53,10 +53,10 @@ class PowerUsageSummaryScreen : PreferenceScreenCreator, R.drawable.ic_settings_battery_white } - - override fun getPreferenceHierarchy(context: Context) = preferenceHierarchy(this) {} + override fun getPreferenceHierarchy(context: Context) = + preferenceHierarchy(this) { +BatteryPercentageSwitchPreference() } companion object { const val KEY = "power_usage_summary_screen" } -} \ No newline at end of file +} diff --git a/tests/robotests/src/com/android/settings/display/BatteryPercentagePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/BatteryPercentagePreferenceControllerTest.java index c84127b04a1..676ae2bfd90 100644 --- a/tests/robotests/src/com/android/settings/display/BatteryPercentagePreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/display/BatteryPercentagePreferenceControllerTest.java @@ -37,9 +37,10 @@ import org.robolectric.annotation.Config; @RunWith(RobolectricTestRunner.class) @Config(shadows = ShadowUtils.class) +// LINT.IfChange public class BatteryPercentagePreferenceControllerTest { - private static final String PREF_KEY = "battery_percentage"; + private static final String PREF_KEY = "status_bar_show_battery_percent"; private Context mContext; private BatteryPercentagePreferenceController mController; @@ -80,3 +81,4 @@ public class BatteryPercentagePreferenceControllerTest { assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE); } } +// LINT.ThenChange(BatteryPercentageSwitchPreferenceTest.kt) diff --git a/tests/robotests/src/com/android/settings/display/BatteryPercentageSwitchPreferenceTest.kt b/tests/robotests/src/com/android/settings/display/BatteryPercentageSwitchPreferenceTest.kt new file mode 100644 index 00000000000..d9a12d57564 --- /dev/null +++ b/tests/robotests/src/com/android/settings/display/BatteryPercentageSwitchPreferenceTest.kt @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2024 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.display + +import android.content.Context +import android.content.ContextWrapper +import android.content.res.Resources +import android.provider.Settings +import androidx.preference.SwitchPreferenceCompat +import androidx.test.core.app.ApplicationProvider +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.android.settings.accessibility.AccessibilityUtil.State.OFF +import com.android.settings.accessibility.AccessibilityUtil.State.ON +import com.android.settings.testutils.shadow.ShadowUtils +import com.android.settingslib.preference.createAndBindWidget +import com.google.common.truth.Truth.assertThat +import org.junit.After +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.ArgumentMatchers.anyInt +import org.mockito.kotlin.doReturn +import org.mockito.kotlin.mock +import org.mockito.kotlin.stub +import org.robolectric.annotation.Config + +@RunWith(AndroidJUnit4::class) +@Config(shadows = [ShadowUtils::class]) +// LINT.IfChange +class BatteryPercentageSwitchPreferenceTest { + private val mockResources = mock() + + private val appContext: Context = ApplicationProvider.getApplicationContext() + + private val context = + object : ContextWrapper(appContext) { + override fun getResources(): Resources = mockResources + } + + private val batteryPercentageSwitchPreference = BatteryPercentageSwitchPreference() + + @After + fun tearDown() { + ShadowUtils.reset() + } + + @Test + fun isAvailable_noBatteryPresent_shouldReturnFalse() { + ShadowUtils.setIsBatteryPresent(false) + + assertThat(batteryPercentageSwitchPreference.isAvailable(context)).isFalse() + } + + @Test + fun isAvailable_batterySettingsAvailable_shouldReturnTrue() { + ShadowUtils.setIsBatteryPresent(true) + mockResources.stub { on { getBoolean(anyInt()) } doReturn true } + + assertThat(batteryPercentageSwitchPreference.isAvailable(context)).isTrue() + } + + @Test + fun isAvailable_batterySettingsUnavailable_shouldReturnFalse() { + ShadowUtils.setIsBatteryPresent(true) + mockResources.stub { on { getBoolean(anyInt()) } doReturn false } + + assertThat(batteryPercentageSwitchPreference.isAvailable(context)).isFalse() + } + + @Test + fun batteryPercentageEnabled_shouldSwitchPreferenceChecked() { + showBatteryPercentage(true) + + val switchPreference = getSwitchPreferenceCompat() + + assertThat(switchPreference.isChecked).isTrue() + } + + @Test + fun batteryPercentageDisabled_shouldSwitchPreferenceUnChecked() { + showBatteryPercentage(false) + + val switchPreference = getSwitchPreferenceCompat() + + assertThat(switchPreference.isChecked).isFalse() + } + + @Test + fun click_defaultBatteryPercentageDisabled_shouldChangeToEnabled() { + showBatteryPercentage(false) + + val switchPreference = getSwitchPreferenceCompat().apply { performClick() } + + assertThat(switchPreference.isChecked).isTrue() + } + + @Test + fun click_defaultBatteryPercentageEnabled_shouldChangeToDisabled() { + showBatteryPercentage(true) + + val switchPreference = getSwitchPreferenceCompat().apply { performClick() } + + assertThat(switchPreference.isChecked).isFalse() + } + + private fun getSwitchPreferenceCompat(): SwitchPreferenceCompat = + batteryPercentageSwitchPreference.createAndBindWidget(context) + + private fun showBatteryPercentage(on: Boolean) = + batteryPercentageSwitchPreference + .storage(context) + .setValue( + Settings.System.SHOW_BATTERY_PERCENT, + Boolean::class.javaObjectType, + on, + ) +} +// LINT.ThenChange(BatteryPercentagePreferenceControllerTest.java)