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.restriction
18 
19 import android.content.Context
20 import com.android.settings.PreferenceRestrictionMixin
21 import com.android.settingslib.datastore.HandlerExecutor
22 import com.android.settingslib.datastore.KeyedObserver
23 import com.android.settingslib.preference.PreferenceScreenBindingHelper
24 import com.android.settingslib.preference.PreferenceScreenBindingHelper.Companion.CHANGE_REASON_STATE
25 
26 /** Helper to rebind preference immediately when user restriction is changed. */
27 class UserRestrictionBindingHelper(
28     context: Context,
29     private val screenBindingHelper: PreferenceScreenBindingHelper,
30 ) : AutoCloseable {
31     private val restrictionKeysToPreferenceKeys: Map<String, MutableSet<String>> =
32         mutableMapOf<String, MutableSet<String>>()
33             .apply {
34                 screenBindingHelper.forEachRecursively {
35                     val metadata = it.metadata
36                     if (metadata is PreferenceRestrictionMixin) {
37                         for (restrictionKey in metadata.restrictionKeys) {
38                             getOrPut(restrictionKey) { mutableSetOf() }.add(metadata.key)
39                         }
40                     }
41                 }
42             }
43             .toMap()
44 
45     private val userRestrictionObserver: KeyedObserver<String?>?
46 
47     init {
48         if (restrictionKeysToPreferenceKeys.isEmpty()) {
49             userRestrictionObserver = null
50         } else {
51             val observer =
52                 KeyedObserver<String?> { restrictionKey, _ ->
53                     restrictionKey?.let { notifyRestrictionChanged(it) }
54                 }
55             UserRestrictions.addObserver(context, observer, HandlerExecutor.main)
56             userRestrictionObserver = observer
57         }
58     }
59 
60     private fun notifyRestrictionChanged(restrictionKey: String) {
61         val keys = restrictionKeysToPreferenceKeys[restrictionKey] ?: return
62         for (key in keys) screenBindingHelper.notifyChange(key, CHANGE_REASON_STATE)
63     }
64 
65     override fun close() {
66         userRestrictionObserver?.let { UserRestrictions.removeObserver(it) }
67     }
68 }
69