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 17 package com.android.settings.display 18 19 import android.app.settings.SettingsEnums.ACTION_AMBIENT_DISPLAY_ALWAYS_ON 20 import android.content.Context 21 import android.hardware.display.AmbientDisplayConfiguration 22 import android.os.SystemProperties 23 import android.os.UserHandle 24 import android.os.UserManager 25 import android.provider.Settings.Secure.DOZE_ALWAYS_ON 26 import com.android.settings.R 27 import com.android.settings.contract.KEY_AMBIENT_DISPLAY_ALWAYS_ON 28 import com.android.settings.display.AmbientDisplayAlwaysOnPreferenceController.isAodSuppressedByBedtime 29 import com.android.settings.metrics.PreferenceActionMetricsProvider 30 import com.android.settings.restriction.PreferenceRestrictionMixin 31 import com.android.settingslib.datastore.AbstractKeyedDataObservable 32 import com.android.settingslib.datastore.HandlerExecutor 33 import com.android.settingslib.datastore.KeyValueStore 34 import com.android.settingslib.datastore.KeyedObserver 35 import com.android.settingslib.datastore.SettingsSecureStore 36 import com.android.settingslib.datastore.SettingsStore 37 import com.android.settingslib.metadata.PreferenceAvailabilityProvider 38 import com.android.settingslib.metadata.PreferenceSummaryProvider 39 import com.android.settingslib.metadata.ReadWritePermit 40 import com.android.settingslib.metadata.SensitivityLevel 41 import com.android.settingslib.metadata.SwitchPreference 42 43 // LINT.IfChange 44 class AmbientDisplayAlwaysOnPreference : 45 SwitchPreference(KEY, R.string.doze_always_on_title, R.string.doze_always_on_summary), 46 PreferenceActionMetricsProvider, 47 PreferenceAvailabilityProvider, 48 PreferenceSummaryProvider, 49 PreferenceRestrictionMixin { 50 51 override val keywords: Int 52 get() = R.string.keywords_always_show_time_info 53 54 override val preferenceActionMetrics: Int 55 get() = ACTION_AMBIENT_DISPLAY_ALWAYS_ON 56 tagsnull57 override fun tags(context: Context) = arrayOf(KEY_AMBIENT_DISPLAY_ALWAYS_ON) 58 59 override val restrictionKeys: Array<String> 60 get() = arrayOf(UserManager.DISALLOW_AMBIENT_DISPLAY) 61 62 override fun isEnabled(context: Context) = super<PreferenceRestrictionMixin>.isEnabled(context) 63 64 override fun isAvailable(context: Context) = 65 !SystemProperties.getBoolean(PROP_AWARE_AVAILABLE, false) && 66 AmbientDisplayConfiguration(context).alwaysOnAvailableForUser(UserHandle.myUserId()) 67 68 override fun getSummary(context: Context): CharSequence? = 69 context.getText( 70 when { 71 isAodSuppressedByBedtime(context) -> R.string.aware_summary_when_bedtime_on 72 else -> R.string.doze_always_on_summary 73 } 74 ) 75 storagenull76 override fun storage(context: Context): KeyValueStore = Storage(context) 77 78 override fun getReadPermissions(context: Context) = SettingsSecureStore.getReadPermissions() 79 80 override fun getWritePermissions(context: Context) = SettingsSecureStore.getWritePermissions() 81 82 override fun getReadPermit(context: Context, callingPid: Int, callingUid: Int) = 83 ReadWritePermit.ALLOW 84 85 override fun getWritePermit( 86 context: Context, 87 value: Boolean?, 88 callingPid: Int, 89 callingUid: Int, 90 ) = ReadWritePermit.ALLOW 91 92 override val sensitivityLevel 93 get() = SensitivityLevel.NO_SENSITIVITY 94 95 /** 96 * Datastore of the preference. 97 * 98 * The preference key and underlying storage key are the different, leverage 99 * [AbstractKeyedDataObservable] to redirect data change event. 100 */ 101 @Suppress("UNCHECKED_CAST") 102 class Storage( 103 private val context: Context, 104 private val settingsStore: SettingsStore = SettingsSecureStore.get(context), 105 ) : AbstractKeyedDataObservable<String>(), KeyedObserver<String>, KeyValueStore { 106 107 override fun contains(key: String) = settingsStore.contains(DOZE_ALWAYS_ON) 108 109 override fun <T : Any> getDefaultValue(key: String, valueType: Class<T>) = 110 context.resources.getBoolean(com.android.internal.R.bool.config_dozeAlwaysOnEnabled) 111 as T 112 113 override fun <T : Any> getValue(key: String, valueType: Class<T>) = 114 settingsStore.getValue(DOZE_ALWAYS_ON, valueType) ?: getDefaultValue(key, valueType) 115 116 override fun <T : Any> setValue(key: String, valueType: Class<T>, value: T?) = 117 settingsStore.setValue(DOZE_ALWAYS_ON, valueType, value) 118 119 override fun onFirstObserverAdded() { 120 // observe the underlying storage key 121 settingsStore.addObserver(DOZE_ALWAYS_ON, this, HandlerExecutor.main) 122 } 123 124 override fun onKeyChanged(key: String, reason: Int) { 125 // forward data change to preference hierarchy key 126 notifyChange(KEY, reason) 127 } 128 129 override fun onLastObserverRemoved() { 130 settingsStore.removeObserver(DOZE_ALWAYS_ON, this) 131 } 132 } 133 134 companion object { 135 const val KEY = KEY_AMBIENT_DISPLAY_ALWAYS_ON 136 private const val PROP_AWARE_AVAILABLE = "ro.vendor.aware_available" 137 } 138 } 139 // LINT.ThenChange(AmbientDisplayAlwaysOnPreferenceController.java) 140