1 /* 2 * Copyright (C) 2024 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.settings.display 17 18 import android.content.Context 19 import android.os.UserManager 20 import android.provider.Settings 21 import android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC 22 import android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL 23 import androidx.preference.Preference 24 import com.android.settings.PreferenceRestrictionMixin 25 import com.android.settings.R 26 import com.android.settings.flags.Flags 27 import com.android.settingslib.PrimarySwitchPreference 28 import com.android.settingslib.datastore.KeyValueStore 29 import com.android.settingslib.datastore.KeyedObservableDelegate 30 import com.android.settingslib.datastore.SettingsStore 31 import com.android.settingslib.datastore.SettingsSystemStore 32 import com.android.settingslib.metadata.BooleanValue 33 import com.android.settingslib.metadata.PersistentPreference 34 import com.android.settingslib.metadata.PreferenceAvailabilityProvider 35 import com.android.settingslib.metadata.PreferenceMetadata 36 import com.android.settingslib.metadata.ProvidePreferenceScreen 37 import com.android.settingslib.metadata.ReadWritePermit 38 import com.android.settingslib.metadata.SensitivityLevel 39 import com.android.settingslib.metadata.preferenceHierarchy 40 import com.android.settingslib.preference.PreferenceScreenBinding 41 import com.android.settingslib.preference.PreferenceScreenCreator 42 43 @ProvidePreferenceScreen 44 class AutoBrightnessScreen : 45 PreferenceScreenCreator, 46 PreferenceScreenBinding, 47 PreferenceAvailabilityProvider, 48 PreferenceRestrictionMixin, 49 PersistentPreference<Boolean>, 50 BooleanValue { 51 override val key: String 52 get() = KEY 53 54 override val title: Int 55 get() = R.string.auto_brightness_title 56 isFlagEnablednull57 override fun isFlagEnabled(context: Context) = Flags.catalystScreenBrightnessMode() 58 59 override fun fragmentClass() = AutoBrightnessSettings::class.java 60 61 override fun hasCompleteHierarchy() = false 62 63 override fun getPreferenceHierarchy(context: Context) = preferenceHierarchy(this) {} 64 storagenull65 override fun storage(context: Context): KeyValueStore = 66 AutoBrightnessDataStore(SettingsSystemStore.get(context)) 67 68 override fun getReadPermit(context: Context, myUid: Int, callingUid: Int) = 69 ReadWritePermit.ALLOW 70 71 override fun getWritePermit(context: Context, value: Boolean?, myUid: Int, callingUid: Int) = 72 ReadWritePermit.ALLOW 73 74 override val sensitivityLevel 75 get() = SensitivityLevel.NO_SENSITIVITY 76 77 override fun isAvailable(context: Context) = 78 context.resources.getBoolean( 79 com.android.internal.R.bool.config_automatic_brightness_available 80 ) 81 82 override fun isEnabled(context: Context) = super<PreferenceRestrictionMixin>.isEnabled(context) 83 84 override val restrictionKeys 85 get() = arrayOf(UserManager.DISALLOW_CONFIG_BRIGHTNESS) 86 87 override val useAdminDisabledSummary: Boolean 88 get() = true 89 90 override fun createWidget(context: Context) = PrimarySwitchPreference(context) 91 92 override fun bind(preference: Preference, metadata: PreferenceMetadata) { 93 super.bind(preference, metadata) 94 (preference as PrimarySwitchPreference).apply { 95 isSwitchEnabled = isEnabled 96 // "true" is not the real default value (it is provided by AutoBrightnessDataStore) 97 isChecked = preferenceDataStore!!.getBoolean(key, true) 98 } 99 } 100 101 /** 102 * The datastore for brightness, which is persisted as integer but the external type is boolean. 103 */ 104 @Suppress("UNCHECKED_CAST") 105 private class AutoBrightnessDataStore(private val settingsStore: SettingsStore) : 106 KeyedObservableDelegate<String>(settingsStore), KeyValueStore { 107 containsnull108 override fun contains(key: String) = settingsStore.contains(key) 109 110 override fun <T : Any> getDefaultValue(key: String, valueType: Class<T>) = 111 DEFAULT_VALUE.toBoolean() as T 112 113 override fun <T : Any> getValue(key: String, valueType: Class<T>) = 114 (settingsStore.getInt(key) ?: DEFAULT_VALUE).toBoolean() as T 115 116 override fun <T : Any> setValue(key: String, valueType: Class<T>, value: T?) = 117 settingsStore.setInt(key, (value as? Boolean)?.toBrightnessMode()) 118 119 /** Converts brightness mode integer to boolean. */ 120 private fun Int.toBoolean() = this == SCREEN_BRIGHTNESS_MODE_AUTOMATIC 121 122 /** Converts boolean value to brightness mode integer. */ 123 private fun Boolean.toBrightnessMode() = 124 if (this) SCREEN_BRIGHTNESS_MODE_AUTOMATIC else SCREEN_BRIGHTNESS_MODE_MANUAL 125 } 126 127 companion object { 128 const val KEY = Settings.System.SCREEN_BRIGHTNESS_MODE 129 private const val DEFAULT_VALUE = SCREEN_BRIGHTNESS_MODE_MANUAL 130 } 131 } 132