diff --git a/src/com/android/settings/SettingsPreferenceFragment.java b/src/com/android/settings/SettingsPreferenceFragment.java index 363d601d0d1..f272c1da9d8 100644 --- a/src/com/android/settings/SettingsPreferenceFragment.java +++ b/src/com/android/settings/SettingsPreferenceFragment.java @@ -17,7 +17,6 @@ package com.android.settings; import static com.android.settings.SettingsActivity.EXTRA_FRAGMENT_ARG_KEY; -import static com.android.settingslib.media.PhoneMediaDevice.isDesktop; import android.app.Activity; import android.app.Dialog; @@ -187,13 +186,6 @@ public abstract class SettingsPreferenceFragment extends InstrumentedPreferenceF /** Returns if catalyst is enabled on current screen. */ public final boolean isCatalystEnabled() { - // TODO(b/379130874): make Catalyst compatible with desktop device, such as user restriction - // check. - Context context = getContext(); - if (context != null && isDesktop(context)) { - return false; - } - return getPreferenceScreenCreator() != null; } diff --git a/src/com/android/settings/restriction/UserRestrictionBindingHelper.kt b/src/com/android/settings/restriction/UserRestrictionBindingHelper.kt index 16104de782f..a1329c2ecdf 100644 --- a/src/com/android/settings/restriction/UserRestrictionBindingHelper.kt +++ b/src/com/android/settings/restriction/UserRestrictionBindingHelper.kt @@ -25,9 +25,9 @@ import com.android.settingslib.preference.PreferenceScreenBindingHelper.Companio /** Helper to rebind preference immediately when user restriction is changed. */ class UserRestrictionBindingHelper( - context: Context, + private val context: Context, private val screenBindingHelper: PreferenceScreenBindingHelper, -) : AutoCloseable { +) : KeyedObserver, AutoCloseable { private val restrictionKeysToPreferenceKeys: Map> = mutableMapOf>() .apply { @@ -42,27 +42,29 @@ class UserRestrictionBindingHelper( } .toMap() - private val userRestrictionObserver: KeyedObserver? - init { - if (restrictionKeysToPreferenceKeys.isEmpty()) { - userRestrictionObserver = null - } else { - val observer = - KeyedObserver { restrictionKey, _ -> - restrictionKey?.let { notifyRestrictionChanged(it) } - } - UserRestrictions.addObserver(context, observer, HandlerExecutor.main) - userRestrictionObserver = observer + val restrictionKeys = restrictionKeysToPreferenceKeys.keys + if (restrictionKeys.isNotEmpty()) { + val userRestrictions = UserRestrictions.get(context) + val executor = HandlerExecutor.main + for (restrictionKey in restrictionKeys) { + userRestrictions.addObserver(restrictionKey, this, executor) + } } } - private fun notifyRestrictionChanged(restrictionKey: String) { + override fun onKeyChanged(restrictionKey: String, reason: Int) { val keys = restrictionKeysToPreferenceKeys[restrictionKey] ?: return for (key in keys) screenBindingHelper.notifyChange(key, CHANGE_REASON_STATE) } override fun close() { - userRestrictionObserver?.let { UserRestrictions.removeObserver(it) } + val restrictionKeys = restrictionKeysToPreferenceKeys.keys + if (restrictionKeys.isNotEmpty()) { + val userRestrictions = UserRestrictions.get(context) + for (restrictionKey in restrictionKeys) { + userRestrictions.removeObserver(restrictionKey, this) + } + } } } diff --git a/src/com/android/settings/restriction/UserRestrictions.kt b/src/com/android/settings/restriction/UserRestrictions.kt index 1fa68307a4a..880aa5d9991 100644 --- a/src/com/android/settings/restriction/UserRestrictions.kt +++ b/src/com/android/settings/restriction/UserRestrictions.kt @@ -16,68 +16,58 @@ package com.android.settings.restriction +import android.content.BroadcastReceiver import android.content.Context -import android.os.Bundle -import android.os.IUserRestrictionsListener +import android.content.Intent +import android.content.IntentFilter import android.os.UserManager -import com.android.settingslib.datastore.KeyedDataObservable +import com.android.settingslib.datastore.AbstractKeyedDataObservable +import com.android.settingslib.datastore.DataChangeReason import com.android.settingslib.datastore.KeyedObserver import java.util.concurrent.Executor -import java.util.concurrent.atomic.AtomicBoolean /** Helper class to monitor user restriction changes. */ -object UserRestrictions { - private val observable = KeyedDataObservable() +class UserRestrictions private constructor(private val applicationContext: Context) { - private val userRestrictionsListener = - object : IUserRestrictionsListener.Stub() { - override fun onUserRestrictionsChanged( - userId: Int, - newRestrictions: Bundle, - prevRestrictions: Bundle, - ) { - // there is no API to remove listener, do a quick check to avoid unnecessary work - if (!observable.hasAnyObserver()) return + private val observable = + object : AbstractKeyedDataObservable() { + override fun onFirstObserverAdded() { + val intentFilter = IntentFilter() + intentFilter.addAction(UserManager.ACTION_USER_RESTRICTIONS_CHANGED) + applicationContext.registerReceiver(broadcastReceiver, intentFilter) + } - val changedKeys = mutableSetOf() - val keys = newRestrictions.keySet() + prevRestrictions.keySet() - for (key in keys) { - if (newRestrictions.getBoolean(key) != prevRestrictions.getBoolean(key)) { - changedKeys.add(key) - } - } - - for (key in changedKeys) observable.notifyChange(key, 0) + override fun onLastObserverRemoved() { + applicationContext.unregisterReceiver(broadcastReceiver) } } - private val listenerAdded = AtomicBoolean() + private val broadcastReceiver: BroadcastReceiver = + object : BroadcastReceiver() { + override fun onReceive(context: Context, intent: Intent) { + // there is no way to get the changed keys, just notify all observers + observable.notifyChange(DataChangeReason.UPDATE) + } + } - fun addObserver(context: Context, observer: KeyedObserver, executor: Executor) { - context.addUserRestrictionsListener() + fun addObserver(observer: KeyedObserver, executor: Executor) = observable.addObserver(observer, executor) - } - fun addObserver( - context: Context, - key: String, - observer: KeyedObserver, - executor: Executor, - ) { - context.addUserRestrictionsListener() + fun addObserver(key: String, observer: KeyedObserver, executor: Executor) = observable.addObserver(key, observer, executor) - } - - private fun Context.addUserRestrictionsListener() { - if (listenerAdded.getAndSet(true)) return - // surprisingly, there is no way to remove the listener - applicationContext - .getSystemService(UserManager::class.java) - .addUserRestrictionsListener(userRestrictionsListener) - } fun removeObserver(observer: KeyedObserver) = observable.removeObserver(observer) fun removeObserver(key: String, observer: KeyedObserver) = observable.removeObserver(key, observer) + + companion object { + @Volatile private var instance: UserRestrictions? = null + + fun get(context: Context) = + instance + ?: synchronized(this) { + instance ?: UserRestrictions(context.applicationContext).also { instance = it } + } + } }