1 /*
<lambda>null2  * 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.content.Context
20 import android.hardware.display.AmbientDisplayConfiguration
21 import android.os.SystemProperties
22 import android.os.UserHandle
23 import android.os.UserManager
24 import android.provider.Settings.Secure.DOZE_ALWAYS_ON
25 import com.android.settings.PreferenceRestrictionMixin
26 import com.android.settings.R
27 import com.android.settings.display.AmbientDisplayAlwaysOnPreferenceController.isAodSuppressedByBedtime
28 import com.android.settingslib.datastore.HandlerExecutor
29 import com.android.settingslib.datastore.KeyValueStore
30 import com.android.settingslib.datastore.KeyedObservableDelegate
31 import com.android.settingslib.datastore.KeyedObserver
32 import com.android.settingslib.datastore.SettingsSecureStore
33 import com.android.settingslib.datastore.SettingsStore
34 import com.android.settingslib.metadata.PreferenceAvailabilityProvider
35 import com.android.settingslib.metadata.PreferenceLifecycleContext
36 import com.android.settingslib.metadata.PreferenceLifecycleProvider
37 import com.android.settingslib.metadata.PreferenceSummaryProvider
38 import com.android.settingslib.metadata.ReadWritePermit
39 import com.android.settingslib.metadata.SensitivityLevel
40 import com.android.settingslib.metadata.SwitchPreference
41 
42 // LINT.IfChange
43 class AmbientDisplayAlwaysOnPreference :
44     SwitchPreference(KEY, R.string.doze_always_on_title, R.string.doze_always_on_summary),
45     PreferenceAvailabilityProvider,
46     PreferenceSummaryProvider,
47     PreferenceLifecycleProvider,
48     PreferenceRestrictionMixin {
49 
50     private var keyMappingObserver: KeyedObserver<String>? = null
51 
52     override val keywords: Int
53         get() = R.string.keywords_always_show_time_info
54 
55     override val restrictionKeys: Array<String>
56         get() = arrayOf(UserManager.DISALLOW_AMBIENT_DISPLAY)
57 
58     override fun isEnabled(context: Context) = super<PreferenceRestrictionMixin>.isEnabled(context)
59 
60     override fun isAvailable(context: Context) =
61         !SystemProperties.getBoolean(PROP_AWARE_AVAILABLE, false) &&
62             AmbientDisplayConfiguration(context).alwaysOnAvailableForUser(UserHandle.myUserId())
63 
64     override fun getSummary(context: Context): CharSequence? =
65         context.getText(
66             when {
67                 isAodSuppressedByBedtime(context) -> R.string.aware_summary_when_bedtime_on
68                 else -> R.string.doze_always_on_summary
69             }
70         )
71 
72     override fun storage(context: Context): KeyValueStore = Storage(context)
73 
74     override fun getReadPermit(context: Context, myUid: Int, callingUid: Int) =
75         ReadWritePermit.ALLOW
76 
77     override fun getWritePermit(context: Context, value: Boolean?, myUid: Int, callingUid: Int) =
78         ReadWritePermit.ALLOW
79 
80     override val sensitivityLevel
81         get() = SensitivityLevel.NO_SENSITIVITY
82 
83     override fun onCreate(context: PreferenceLifecycleContext) {
84         val storage = SettingsSecureStore.get(context)
85         keyMappingObserver =
86             KeyedObserver<String> { _, reason -> storage.notifyChange(KEY, reason) }
87                 .also { storage.addObserver(DOZE_ALWAYS_ON, it, HandlerExecutor.main) }
88     }
89 
90     override fun onDestroy(context: PreferenceLifecycleContext) {
91         keyMappingObserver?.let {
92             SettingsSecureStore.get(context).removeObserver(DOZE_ALWAYS_ON, it)
93         }
94     }
95 
96     @Suppress("UNCHECKED_CAST")
97     class Storage(
98         private val context: Context,
99         private val settingsStore: SettingsStore = SettingsSecureStore.get(context),
100     ) : KeyedObservableDelegate<String>(settingsStore), KeyValueStore {
101 
102         override fun contains(key: String) = settingsStore.contains(DOZE_ALWAYS_ON)
103 
104         override fun <T : Any> getDefaultValue(key: String, valueType: Class<T>) =
105             context.resources.getBoolean(com.android.internal.R.bool.config_dozeAlwaysOnEnabled)
106                 as T
107 
108         override fun <T : Any> getValue(key: String, valueType: Class<T>) =
109             settingsStore.getValue(DOZE_ALWAYS_ON, valueType) ?: getDefaultValue(key, valueType)
110 
111         override fun <T : Any> setValue(key: String, valueType: Class<T>, value: T?) =
112             settingsStore.setValue(DOZE_ALWAYS_ON, valueType, value)
113     }
114 
115     companion object {
116         const val KEY = "ambient_display_always_on"
117         private const val PROP_AWARE_AVAILABLE = "ro.vendor.aware_available"
118     }
119 }
120 // LINT.ThenChange(AmbientDisplayAlwaysOnPreferenceController.java)
121