• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.app.settings.SettingsEnums.ACTION_SCREEN_ATTENTION_CHANGED
20 import android.content.BroadcastReceiver
21 import android.content.Context
22 import android.content.Intent
23 import android.content.IntentFilter
24 import android.hardware.SensorPrivacyManager
25 import android.hardware.SensorPrivacyManager.OnSensorPrivacyChangedListener
26 import android.hardware.SensorPrivacyManager.Sensors.CAMERA
27 import android.os.PowerManager
28 import android.os.UserManager
29 import android.provider.Settings
30 import com.android.settings.R
31 import com.android.settings.contract.KEY_SCREEN_ATTENTION
32 import com.android.settings.metrics.PreferenceActionMetricsProvider
33 import com.android.settings.restriction.PreferenceRestrictionMixin
34 import com.android.settingslib.RestrictedSwitchPreference
35 import com.android.settingslib.datastore.KeyValueStore
36 import com.android.settingslib.datastore.KeyValueStoreDelegate
37 import com.android.settingslib.datastore.SettingsSecureStore
38 import com.android.settingslib.metadata.BooleanValuePreference
39 import com.android.settingslib.metadata.PreferenceAvailabilityProvider
40 import com.android.settingslib.metadata.PreferenceLifecycleContext
41 import com.android.settingslib.metadata.PreferenceLifecycleProvider
42 import com.android.settingslib.metadata.ReadWritePermit
43 import com.android.settingslib.metadata.SensitivityLevel
44 import com.android.settingslib.preference.PreferenceBindingPlaceholder
45 import com.android.settingslib.preference.SwitchPreferenceBinding
46 
47 // LINT.IfChange
48 class AdaptiveSleepPreference :
49     BooleanValuePreference,
50     SwitchPreferenceBinding,
51     PreferenceActionMetricsProvider,
52     PreferenceLifecycleProvider,
53     PreferenceBindingPlaceholder, // not needed once controller class is cleaned up
54     PreferenceAvailabilityProvider,
55     PreferenceRestrictionMixin {
56 
57     private var broadcastReceiver: BroadcastReceiver? = null
58     private var sensorPrivacyChangedListener: OnSensorPrivacyChangedListener? = null
59 
60     override val key: String
61         get() = KEY
62 
63     override val title: Int
64         get() = R.string.adaptive_sleep_title
65 
66     override val summary: Int
67         get() = R.string.adaptive_sleep_description
68 
69     override val preferenceActionMetrics: Int
70         get() = ACTION_SCREEN_ATTENTION_CHANGED
71 
72     override fun tags(context: Context) = arrayOf(KEY_SCREEN_ATTENTION)
73 
74     override fun isIndexable(context: Context) = false
75 
76     override fun isEnabled(context: Context) =
77         super<PreferenceRestrictionMixin>.isEnabled(context) && context.canBeEnabled()
78 
79     override val restrictionKeys: Array<String>
80         get() = arrayOf(UserManager.DISALLOW_CONFIG_SCREEN_TIMEOUT)
81 
82     override fun isAvailable(context: Context) = context.isAdaptiveSleepSupported()
83 
84     override fun createWidget(context: Context) = RestrictedSwitchPreference(context)
85 
86     override fun storage(context: Context): KeyValueStore = Storage(context)
87 
88     override fun getReadPermissions(context: Context) = SettingsSecureStore.getReadPermissions()
89 
90     override fun getWritePermissions(context: Context) = SettingsSecureStore.getWritePermissions()
91 
92     override fun getReadPermit(context: Context, callingPid: Int, callingUid: Int) =
93         ReadWritePermit.ALLOW
94 
95     override fun getWritePermit(
96         context: Context,
97         value: Boolean?,
98         callingPid: Int,
99         callingUid: Int,
100     ) = ReadWritePermit.ALLOW
101 
102     override val sensitivityLevel
103         get() = SensitivityLevel.NO_SENSITIVITY
104 
105     @Suppress("UNCHECKED_CAST")
106     private class Storage(
107         private val context: Context,
108         private val settingsStore: KeyValueStore = SettingsSecureStore.get(context),
109     ) : KeyValueStoreDelegate {
110 
111         override val keyValueStoreDelegate
112             get() = settingsStore
113 
114         override fun <T : Any> getValue(key: String, valueType: Class<T>) =
115             (context.canBeEnabled() && settingsStore.getBoolean(key) == true) as T
116     }
117 
118     override fun onStart(context: PreferenceLifecycleContext) {
119         val receiver =
120             object : BroadcastReceiver() {
121                 override fun onReceive(receiverContext: Context, intent: Intent) {
122                     context.notifyPreferenceChange(KEY)
123                 }
124             }
125         context.registerReceiver(
126             receiver,
127             IntentFilter(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED),
128         )
129         broadcastReceiver = receiver
130 
131         val listener = OnSensorPrivacyChangedListener { _, _ ->
132             context.notifyPreferenceChange(KEY)
133         }
134         SensorPrivacyManager.getInstance(context).addSensorPrivacyListener(CAMERA, listener)
135         sensorPrivacyChangedListener = listener
136     }
137 
138     override fun onStop(context: PreferenceLifecycleContext) {
139         broadcastReceiver?.let { context.unregisterReceiver(it) }
140         sensorPrivacyChangedListener?.let {
141             SensorPrivacyManager.getInstance(context).removeSensorPrivacyListener(it)
142         }
143     }
144 
145     companion object {
146         const val KEY = Settings.Secure.ADAPTIVE_SLEEP
147 
148         @Suppress("DEPRECATION")
149         private fun Context.canBeEnabled() =
150             AdaptiveSleepPreferenceController.hasSufficientPermission(packageManager) &&
151                 getSystemService(PowerManager::class.java)?.isPowerSaveMode != true &&
152                 !SensorPrivacyManager.getInstance(this).isSensorPrivacyEnabled(CAMERA)
153     }
154 }
155 // LINT.ThenChange(AdaptiveSleepPreferenceController.java)
156