blob: a3ecf7db2863370ccd69c33981bcc1309a385d3a [file] [log] [blame]
/*
* Copyright (C) 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.restriction
import android.content.Context
import androidx.lifecycle.lifecycleScope
import androidx.preference.PreferenceFragmentCompat
import com.android.settingslib.datastore.HandlerExecutor
import com.android.settingslib.datastore.KeyedObserver
import com.android.settingslib.metadata.PreferenceChangeReason
import com.android.settingslib.metadata.PreferenceHierarchyNode
import com.android.settingslib.preference.PreferenceScreenBindingHelper
/** Helper to rebind preference immediately when user restriction is changed. */
class UserRestrictionBindingHelper(
fragment: PreferenceFragmentCompat,
private val screenBindingHelper: PreferenceScreenBindingHelper,
) : KeyedObserver<String>, AutoCloseable {
private val context: Context = fragment.requireContext()
private val restrictionKeysToPreferenceKeys = mutableMapOf<String, MutableSet<String>>()
init {
screenBindingHelper.forEachAsyncRecursively(::addNode, fragment.lifecycleScope) { _, node ->
// node is added to hierarchy in async manner
addNode(node)
}
}
private fun addNode(node: PreferenceHierarchyNode) {
val metadata = node.metadata
val restrictionKeys =
(metadata as? PreferenceRestrictionMixin)?.restrictionKeys ?: emptyArray()
if (restrictionKeys.isEmpty()) return
val userRestrictions = UserRestrictions.get(context)
val executor = HandlerExecutor.main
fun addObserver(restrictionKey: String) =
userRestrictions.addObserver(
restrictionKey,
this@UserRestrictionBindingHelper,
executor,
)
val key = metadata.key
for (restrictionKey in restrictionKeys) {
restrictionKeysToPreferenceKeys
.getOrPut(restrictionKey) {
addObserver(restrictionKey)
mutableSetOf()
}
.add(key)
}
}
override fun onKeyChanged(restrictionKey: String, reason: Int) {
val keys = restrictionKeysToPreferenceKeys[restrictionKey] ?: return
for (key in keys) screenBindingHelper.notifyChange(key, PreferenceChangeReason.STATE)
}
override fun close() {
val restrictionKeys = restrictionKeysToPreferenceKeys.keys
if (restrictionKeys.isNotEmpty()) {
val userRestrictions = UserRestrictions.get(context)
for (restrictionKey in restrictionKeys) {
userRestrictions.removeObserver(restrictionKey, this)
}
}
}
}