Loading packages/SettingsLib/DataStore/src/com/android/settingslib/datastore/KeyedObserver.kt +60 −1 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import androidx.collection.MutableScatterMap import com.google.errorprone.annotations.CanIgnoreReturnValue import java.util.WeakHashMap import java.util.concurrent.Executor import java.util.concurrent.atomic.AtomicInteger /** * Callback to be informed of changes in [KeyedObservable] object. Loading Loading @@ -203,13 +204,71 @@ open class KeyedDataObservable<K> : KeyedObservable<K> { } } fun hasAnyObserver(): Boolean { open fun hasAnyObserver(): Boolean { synchronized(observers) { if (observers.isNotEmpty()) return true } synchronized(keyedObservers) { if (keyedObservers.isNotEmpty()) return true } return false } } /** [KeyedDataObservable] that maintains a counter for the observers. */ abstract class AbstractKeyedDataObservable<K> : KeyedDataObservable<K>() { /** * Counter of observers. * * The value is accurate only when [addObserver] and [removeObserver] are invoked in pairs. */ private val counter = AtomicInteger() override fun addObserver(observer: KeyedObserver<K?>, executor: Executor) = if (super.addObserver(observer, executor)) { onObserverAdded() true } else { false } override fun addObserver(key: K, observer: KeyedObserver<K>, executor: Executor) = if (super.addObserver(key, observer, executor)) { onObserverAdded() true } else { false } private fun onObserverAdded() { if (counter.getAndIncrement() == 0) onFirstObserverAdded() } /** Callbacks when the first observer is just added. */ protected abstract fun onFirstObserverAdded() override fun removeObserver(observer: KeyedObserver<K?>) = if (super.removeObserver(observer)) { onObserverRemoved() true } else { false } override fun removeObserver(key: K, observer: KeyedObserver<K>) = if (super.removeObserver(key, observer)) { onObserverRemoved() true } else { false } private fun onObserverRemoved() { if (counter.decrementAndGet() == 0) onLastObserverRemoved() } /** Callbacks when the last observer is just removed. */ protected abstract fun onLastObserverRemoved() override fun hasAnyObserver() = counter.get() > 0 } /** [KeyedObservable] with no-op implementations for all interfaces. */ open class NoOpKeyedObservable<K> : KeyedObservable<K> { Loading packages/SettingsLib/DataStore/src/com/android/settingslib/datastore/SettingsStore.kt +5 −50 Original line number Diff line number Diff line Loading @@ -20,21 +20,10 @@ import android.content.ContentResolver import android.database.ContentObserver import android.net.Uri import android.util.Log import java.util.concurrent.Executor import java.util.concurrent.atomic.AtomicInteger /** Base class of the Settings provider data stores. */ abstract class SettingsStore(protected val contentResolver: ContentResolver) : KeyedDataObservable<String>(), KeyValueStore { /** * Counter of observers. * * The value is accurate only when [addObserver] and [removeObserver] are called correctly. When * an observer is not removed (and its weak reference is garbage collected), the content * observer is not unregistered but this is not a big deal. */ private val counter = AtomicInteger() AbstractKeyedDataObservable<String>(), KeyValueStore { private val contentObserver = object : ContentObserver(HandlerExecutor.main) { Loading @@ -48,49 +37,15 @@ abstract class SettingsStore(protected val contentResolver: ContentResolver) : } } override fun addObserver(observer: KeyedObserver<String?>, executor: Executor) = if (super.addObserver(observer, executor)) { onObserverAdded() true } else { false } override fun addObserver(key: String, observer: KeyedObserver<String>, executor: Executor) = if (super.addObserver(key, observer, executor)) { onObserverAdded() true } else { false } private fun onObserverAdded() { if (counter.getAndIncrement() != 0) return Log.i(tag, "registerContentObserver") contentResolver.registerContentObserver(uri, true, contentObserver) } /** The URI to watch for any key change. */ protected abstract val uri: Uri override fun removeObserver(observer: KeyedObserver<String?>) = if (super.removeObserver(observer)) { onObserverRemoved() true } else { false } override fun removeObserver(key: String, observer: KeyedObserver<String>) = if (super.removeObserver(key, observer)) { onObserverRemoved() true } else { false override fun onFirstObserverAdded() { Log.i(tag, "registerContentObserver") contentResolver.registerContentObserver(uri, true, contentObserver) } private fun onObserverRemoved() { if (counter.decrementAndGet() != 0) return override fun onLastObserverRemoved() { Log.i(tag, "unregisterContentObserver") contentResolver.unregisterContentObserver(contentObserver) } Loading Loading
packages/SettingsLib/DataStore/src/com/android/settingslib/datastore/KeyedObserver.kt +60 −1 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import androidx.collection.MutableScatterMap import com.google.errorprone.annotations.CanIgnoreReturnValue import java.util.WeakHashMap import java.util.concurrent.Executor import java.util.concurrent.atomic.AtomicInteger /** * Callback to be informed of changes in [KeyedObservable] object. Loading Loading @@ -203,13 +204,71 @@ open class KeyedDataObservable<K> : KeyedObservable<K> { } } fun hasAnyObserver(): Boolean { open fun hasAnyObserver(): Boolean { synchronized(observers) { if (observers.isNotEmpty()) return true } synchronized(keyedObservers) { if (keyedObservers.isNotEmpty()) return true } return false } } /** [KeyedDataObservable] that maintains a counter for the observers. */ abstract class AbstractKeyedDataObservable<K> : KeyedDataObservable<K>() { /** * Counter of observers. * * The value is accurate only when [addObserver] and [removeObserver] are invoked in pairs. */ private val counter = AtomicInteger() override fun addObserver(observer: KeyedObserver<K?>, executor: Executor) = if (super.addObserver(observer, executor)) { onObserverAdded() true } else { false } override fun addObserver(key: K, observer: KeyedObserver<K>, executor: Executor) = if (super.addObserver(key, observer, executor)) { onObserverAdded() true } else { false } private fun onObserverAdded() { if (counter.getAndIncrement() == 0) onFirstObserverAdded() } /** Callbacks when the first observer is just added. */ protected abstract fun onFirstObserverAdded() override fun removeObserver(observer: KeyedObserver<K?>) = if (super.removeObserver(observer)) { onObserverRemoved() true } else { false } override fun removeObserver(key: K, observer: KeyedObserver<K>) = if (super.removeObserver(key, observer)) { onObserverRemoved() true } else { false } private fun onObserverRemoved() { if (counter.decrementAndGet() == 0) onLastObserverRemoved() } /** Callbacks when the last observer is just removed. */ protected abstract fun onLastObserverRemoved() override fun hasAnyObserver() = counter.get() > 0 } /** [KeyedObservable] with no-op implementations for all interfaces. */ open class NoOpKeyedObservable<K> : KeyedObservable<K> { Loading
packages/SettingsLib/DataStore/src/com/android/settingslib/datastore/SettingsStore.kt +5 −50 Original line number Diff line number Diff line Loading @@ -20,21 +20,10 @@ import android.content.ContentResolver import android.database.ContentObserver import android.net.Uri import android.util.Log import java.util.concurrent.Executor import java.util.concurrent.atomic.AtomicInteger /** Base class of the Settings provider data stores. */ abstract class SettingsStore(protected val contentResolver: ContentResolver) : KeyedDataObservable<String>(), KeyValueStore { /** * Counter of observers. * * The value is accurate only when [addObserver] and [removeObserver] are called correctly. When * an observer is not removed (and its weak reference is garbage collected), the content * observer is not unregistered but this is not a big deal. */ private val counter = AtomicInteger() AbstractKeyedDataObservable<String>(), KeyValueStore { private val contentObserver = object : ContentObserver(HandlerExecutor.main) { Loading @@ -48,49 +37,15 @@ abstract class SettingsStore(protected val contentResolver: ContentResolver) : } } override fun addObserver(observer: KeyedObserver<String?>, executor: Executor) = if (super.addObserver(observer, executor)) { onObserverAdded() true } else { false } override fun addObserver(key: String, observer: KeyedObserver<String>, executor: Executor) = if (super.addObserver(key, observer, executor)) { onObserverAdded() true } else { false } private fun onObserverAdded() { if (counter.getAndIncrement() != 0) return Log.i(tag, "registerContentObserver") contentResolver.registerContentObserver(uri, true, contentObserver) } /** The URI to watch for any key change. */ protected abstract val uri: Uri override fun removeObserver(observer: KeyedObserver<String?>) = if (super.removeObserver(observer)) { onObserverRemoved() true } else { false } override fun removeObserver(key: String, observer: KeyedObserver<String>) = if (super.removeObserver(key, observer)) { onObserverRemoved() true } else { false override fun onFirstObserverAdded() { Log.i(tag, "registerContentObserver") contentResolver.registerContentObserver(uri, true, contentObserver) } private fun onObserverRemoved() { if (counter.decrementAndGet() != 0) return override fun onLastObserverRemoved() { Log.i(tag, "unregisterContentObserver") contentResolver.unregisterContentObserver(contentObserver) } Loading