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

Commit 14ba0b65 authored by Fan Wu's avatar Fan Wu Committed by Android (Google) Code Review
Browse files

Merge "Revert "Revert "Migrate Battery percentage preference into catal..."" into main

parents 33008bc6 a794e01d
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -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 {

@@ -84,3 +85,4 @@ public class BatteryPercentagePreferenceController extends BasePreferenceControl
        return true;
    }
}
// LINT.ThenChange(BatteryPercentageSwitchPreference.kt)
+95 −0
Original line number Diff line number Diff line
/*
 * 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<String>(settingsStore), KeyValueStore {

        override fun contains(key: String) = settingsStore.contains(KEY)

        override fun <T : Any> getValue(key: String, valueType: Class<T>) =
            (settingsStore.getBoolean(key) ?: getDefaultValue(key, valueType)) as T

        override fun <T : Any> setValue(key: String, valueType: Class<T>, value: T?) {
            settingsStore.setBoolean(key, value as Boolean)
        }

        override fun <T : Any> getDefaultValue(key: String, valueType: Class<T>) =
            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)
+6 −6
Original line number Diff line number Diff line
@@ -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,8 +53,8 @@ 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"
+3 −1
Original line number Diff line number Diff line
@@ -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)
+130 −0
Original line number Diff line number Diff line
/*
 * 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<Resources>()

    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)