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.app.settings.SettingsEnums.ACTION_ADAPTIVE_BRIGHTNESS 19 import android.content.Context 20 import android.os.UserManager 21 import android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE 22 import android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC 23 import android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL 24 import com.android.settings.R 25 import com.android.settings.contract.KEY_ADAPTIVE_BRIGHTNESS 26 import com.android.settings.flags.Flags 27 import com.android.settings.metrics.PreferenceActionMetricsProvider 28 import com.android.settings.restriction.PreferenceRestrictionMixin 29 import com.android.settingslib.PrimarySwitchPreferenceBinding 30 import com.android.settingslib.datastore.AbstractKeyedDataObservable 31 import com.android.settingslib.datastore.HandlerExecutor 32 import com.android.settingslib.datastore.KeyValueStore 33 import com.android.settingslib.datastore.KeyedObserver 34 import com.android.settingslib.datastore.SettingsStore 35 import com.android.settingslib.datastore.SettingsSystemStore 36 import com.android.settingslib.metadata.BooleanValuePreference 37 import com.android.settingslib.metadata.PreferenceAvailabilityProvider 38 import com.android.settingslib.metadata.ProvidePreferenceScreen 39 import com.android.settingslib.metadata.ReadWritePermit 40 import com.android.settingslib.metadata.SensitivityLevel 41 import com.android.settingslib.metadata.preferenceHierarchy 42 import com.android.settingslib.preference.PreferenceScreenCreator 43 44 @ProvidePreferenceScreen(AutoBrightnessScreen.KEY) 45 class AutoBrightnessScreen : 46 PreferenceScreenCreator, 47 PrimarySwitchPreferenceBinding, 48 PreferenceActionMetricsProvider, 49 PreferenceAvailabilityProvider, 50 PreferenceRestrictionMixin, 51 BooleanValuePreference { 52 override val key: String 53 get() = KEY 54 55 override val title: Int 56 get() = R.string.auto_brightness_title 57 58 override val preferenceActionMetrics: Int 59 get() = ACTION_ADAPTIVE_BRIGHTNESS 60 tagsnull61 override fun tags(context: Context) = arrayOf(KEY_ADAPTIVE_BRIGHTNESS) 62 63 override fun isFlagEnabled(context: Context) = Flags.catalystScreenBrightnessMode() 64 65 override fun fragmentClass() = AutoBrightnessSettings::class.java 66 67 override fun hasCompleteHierarchy() = false 68 69 override fun getPreferenceHierarchy(context: Context) = preferenceHierarchy(context, this) {} 70 storagenull71 override fun storage(context: Context): KeyValueStore = 72 AutoBrightnessDataStore(SettingsSystemStore.get(context)) 73 74 override fun getReadPermissions(context: Context) = SettingsSystemStore.getReadPermissions() 75 76 override fun getWritePermissions(context: Context) = SettingsSystemStore.getWritePermissions() 77 78 override fun getReadPermit(context: Context, callingPid: Int, callingUid: Int) = 79 ReadWritePermit.ALLOW 80 81 override fun getWritePermit( 82 context: Context, 83 value: Boolean?, 84 callingPid: Int, 85 callingUid: Int, 86 ) = ReadWritePermit.ALLOW 87 88 override val sensitivityLevel 89 get() = SensitivityLevel.NO_SENSITIVITY 90 91 override fun isAvailable(context: Context) = 92 context.resources.getBoolean( 93 com.android.internal.R.bool.config_automatic_brightness_available 94 ) 95 96 override fun isEnabled(context: Context) = super<PreferenceRestrictionMixin>.isEnabled(context) 97 98 override val restrictionKeys 99 get() = arrayOf(UserManager.DISALLOW_CONFIG_BRIGHTNESS) 100 101 override val useAdminDisabledSummary: Boolean 102 get() = true 103 104 /** 105 * The datastore for brightness, which is persisted as integer but the external type is boolean. 106 */ 107 @Suppress("UNCHECKED_CAST") 108 private class AutoBrightnessDataStore(private val settingsStore: SettingsStore) : 109 AbstractKeyedDataObservable<String>(), KeyedObserver<String>, KeyValueStore { 110 111 override fun contains(key: String) = settingsStore.contains(SCREEN_BRIGHTNESS_MODE) 112 113 override fun <T : Any> getDefaultValue(key: String, valueType: Class<T>) = 114 DEFAULT_VALUE.toBoolean() as T 115 116 override fun <T : Any> getValue(key: String, valueType: Class<T>) = 117 (settingsStore.getInt(SCREEN_BRIGHTNESS_MODE) ?: DEFAULT_VALUE).toBoolean() as T 118 119 override fun <T : Any> setValue(key: String, valueType: Class<T>, value: T?) = 120 settingsStore.setInt(SCREEN_BRIGHTNESS_MODE, (value as? Boolean)?.toBrightnessMode()) 121 122 override fun onFirstObserverAdded() { 123 // observe the underlying storage key 124 settingsStore.addObserver(SCREEN_BRIGHTNESS_MODE, this, HandlerExecutor.main) 125 } 126 127 override fun onKeyChanged(key: String, reason: Int) { 128 // forward data change to preference hierarchy key 129 notifyChange(KEY, reason) 130 } 131 132 override fun onLastObserverRemoved() { 133 settingsStore.removeObserver(SCREEN_BRIGHTNESS_MODE, this) 134 } 135 136 /** Converts brightness mode integer to boolean. */ 137 private fun Int.toBoolean() = this == SCREEN_BRIGHTNESS_MODE_AUTOMATIC 138 139 /** Converts boolean value to brightness mode integer. */ 140 private fun Boolean.toBrightnessMode() = 141 if (this) SCREEN_BRIGHTNESS_MODE_AUTOMATIC else SCREEN_BRIGHTNESS_MODE_MANUAL 142 } 143 144 companion object { 145 const val KEY = "auto_brightness_entry" 146 private const val DEFAULT_VALUE = SCREEN_BRIGHTNESS_MODE_MANUAL 147 } 148 } 149