Loading src/com/android/settings/SettingsPreferenceFragment.java +0 −8 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; } Loading src/com/android/settings/restriction/UserRestrictionBindingHelper.kt +17 −15 Original line number Diff line number Diff line Loading @@ -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<String>, AutoCloseable { private val restrictionKeysToPreferenceKeys: Map<String, MutableSet<String>> = mutableMapOf<String, MutableSet<String>>() .apply { Loading @@ -42,27 +42,29 @@ class UserRestrictionBindingHelper( } .toMap() private val userRestrictionObserver: KeyedObserver<String?>? init { if (restrictionKeysToPreferenceKeys.isEmpty()) { userRestrictionObserver = null } else { val observer = KeyedObserver<String?> { restrictionKey, _ -> restrictionKey?.let { notifyRestrictionChanged(it) } 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) } UserRestrictions.addObserver(context, observer, HandlerExecutor.main) userRestrictionObserver = observer } } 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) } } } } src/com/android/settings/restriction/UserRestrictions.kt +34 −44 Original line number Diff line number Diff line Loading @@ -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<String>() 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<String>() { override fun onFirstObserverAdded() { val intentFilter = IntentFilter() intentFilter.addAction(UserManager.ACTION_USER_RESTRICTIONS_CHANGED) applicationContext.registerReceiver(broadcastReceiver, intentFilter) } val changedKeys = mutableSetOf<String>() val keys = newRestrictions.keySet() + prevRestrictions.keySet() for (key in keys) { if (newRestrictions.getBoolean(key) != prevRestrictions.getBoolean(key)) { changedKeys.add(key) override fun onLastObserverRemoved() { applicationContext.unregisterReceiver(broadcastReceiver) } } for (key in changedKeys) observable.notifyChange(key, 0) 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) } } private val listenerAdded = AtomicBoolean() fun addObserver(context: Context, observer: KeyedObserver<String?>, executor: Executor) { context.addUserRestrictionsListener() fun addObserver(observer: KeyedObserver<String?>, executor: Executor) = observable.addObserver(observer, executor) } fun addObserver( context: Context, key: String, observer: KeyedObserver<String>, executor: Executor, ) { context.addUserRestrictionsListener() fun addObserver(key: String, observer: KeyedObserver<String>, 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<String?>) = observable.removeObserver(observer) fun removeObserver(key: String, observer: KeyedObserver<String>) = 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 } } } } Loading
src/com/android/settings/SettingsPreferenceFragment.java +0 −8 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; } Loading
src/com/android/settings/restriction/UserRestrictionBindingHelper.kt +17 −15 Original line number Diff line number Diff line Loading @@ -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<String>, AutoCloseable { private val restrictionKeysToPreferenceKeys: Map<String, MutableSet<String>> = mutableMapOf<String, MutableSet<String>>() .apply { Loading @@ -42,27 +42,29 @@ class UserRestrictionBindingHelper( } .toMap() private val userRestrictionObserver: KeyedObserver<String?>? init { if (restrictionKeysToPreferenceKeys.isEmpty()) { userRestrictionObserver = null } else { val observer = KeyedObserver<String?> { restrictionKey, _ -> restrictionKey?.let { notifyRestrictionChanged(it) } 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) } UserRestrictions.addObserver(context, observer, HandlerExecutor.main) userRestrictionObserver = observer } } 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) } } } }
src/com/android/settings/restriction/UserRestrictions.kt +34 −44 Original line number Diff line number Diff line Loading @@ -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<String>() 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<String>() { override fun onFirstObserverAdded() { val intentFilter = IntentFilter() intentFilter.addAction(UserManager.ACTION_USER_RESTRICTIONS_CHANGED) applicationContext.registerReceiver(broadcastReceiver, intentFilter) } val changedKeys = mutableSetOf<String>() val keys = newRestrictions.keySet() + prevRestrictions.keySet() for (key in keys) { if (newRestrictions.getBoolean(key) != prevRestrictions.getBoolean(key)) { changedKeys.add(key) override fun onLastObserverRemoved() { applicationContext.unregisterReceiver(broadcastReceiver) } } for (key in changedKeys) observable.notifyChange(key, 0) 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) } } private val listenerAdded = AtomicBoolean() fun addObserver(context: Context, observer: KeyedObserver<String?>, executor: Executor) { context.addUserRestrictionsListener() fun addObserver(observer: KeyedObserver<String?>, executor: Executor) = observable.addObserver(observer, executor) } fun addObserver( context: Context, key: String, observer: KeyedObserver<String>, executor: Executor, ) { context.addUserRestrictionsListener() fun addObserver(key: String, observer: KeyedObserver<String>, 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<String?>) = observable.removeObserver(observer) fun removeObserver(key: String, observer: KeyedObserver<String>) = 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 } } } }