diff options
author | 2021-11-02 20:44:54 -0400 | |
---|---|---|
committer | 2021-11-03 11:20:11 -0400 | |
commit | 72a500295689cb960a98f40bfe03a0043f300f64 (patch) | |
tree | aad115466218be59510b8076b3353c34fd274be9 | |
parent | 1a934e9aee4571974a7b7687dcb03dbff0acfcfe (diff) |
Add support for flag change listeners library.
Bug: 203548827
Test: manual
Change-Id: I6f989e89a98c7c6643af762eb0263f81ce584dfa
7 files changed, 66 insertions, 11 deletions
diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp index 16a6a463512e..eae6f27db738 100644 --- a/packages/SystemUI/Android.bp +++ b/packages/SystemUI/Android.bp @@ -83,8 +83,7 @@ android_library { "src/**/*.kt", "src/**/*.java", "src/**/I*.aidl", - "src-release/**/*.kt", - "src-release/**/*.java", + ":ReleaseJavaFiles", ], product_variables: { debuggable: { diff --git a/packages/SystemUI/docs/plugins.md b/packages/SystemUI/docs/plugins.md index 689200577aad..378cba5155ab 100644 --- a/packages/SystemUI/docs/plugins.md +++ b/packages/SystemUI/docs/plugins.md @@ -1,3 +1,4 @@ + # SystemUI Plugins Plugins provide an easy way to rapidly prototype SystemUI features. Plugins are APKs that will be installable only on Build.IS_DEBUGGABLE (dogfood) builds, that can change the behavior of SystemUI at runtime. This is done by creating a basic set of interfaces that the plugins can expect to be in SysUI, then the portion of code controlled by the interface can be iterated on faster than currently. diff --git a/packages/SystemUI/shared/Android.bp b/packages/SystemUI/shared/Android.bp index 7cf22a38837b..25db478e57b7 100644 --- a/packages/SystemUI/shared/Android.bp +++ b/packages/SystemUI/shared/Android.bp @@ -75,10 +75,10 @@ java_library { static_kotlin_stdlib: false, libs: [ "androidx.concurrent_concurrent-futures", - "SystemUI-flags", ], static_libs: [ "SystemUI-flag-types", + "SystemUI-flags", ], java_version: "1.8", min_sdk_version: "current", diff --git a/packages/SystemUI/shared/src/com/android/systemui/flags/FlagManager.kt b/packages/SystemUI/shared/src/com/android/systemui/flags/FlagManager.kt index 3125faf3e96e..cbb942bc3015 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/flags/FlagManager.kt +++ b/packages/SystemUI/shared/src/com/android/systemui/flags/FlagManager.kt @@ -18,13 +18,19 @@ package com.android.systemui.flags import android.content.Context import android.content.Intent +import android.database.ContentObserver +import android.net.Uri +import android.os.Handler import android.provider.Settings import androidx.concurrent.futures.CallbackToFutureAdapter import com.google.common.util.concurrent.ListenableFuture import org.json.JSONException import org.json.JSONObject -class FlagManager constructor(val context: Context) : FlagReader { +class FlagManager constructor( + private val context: Context, + private val handler: Handler +) : FlagReader { companion object { const val RECEIVING_PACKAGE = "com.android.systemui" const val ACTION_SET_FLAG = "com.android.systemui.action.SET_FLAG" @@ -36,6 +42,9 @@ class FlagManager constructor(val context: Context) : FlagReader { private const val SETTINGS_PREFIX = "systemui/flags" } + private val listeners: MutableSet<FlagReader.Listener> = mutableSetOf() + private val settingsObserver: ContentObserver = SettingsObserver() + fun getFlagsFuture(): ListenableFuture<Collection<Flag<*>>> { val knownFlagMap = Flags.collectFlags() // Possible todo in the future: query systemui async to actually get the known flag ids. @@ -82,6 +91,27 @@ class FlagManager constructor(val context: Context) : FlagReader { } } + override fun addListener(listener: FlagReader.Listener) { + synchronized(listeners) { + val registerNeeded = listeners.isEmpty() + listeners.add(listener) + if (registerNeeded) { + context.contentResolver.registerContentObserver( + Settings.Secure.getUriFor(SETTINGS_PREFIX), true, settingsObserver) + } + } + } + + override fun removeListener(listener: FlagReader.Listener) { + synchronized(listeners) { + val isRegistered = !listeners.isEmpty() + listeners.remove(listener) + if (isRegistered && listeners.isEmpty()) { + context.contentResolver.unregisterContentObserver(settingsObserver) + } + } + } + private fun createIntent(id: Int): Intent { val intent = Intent(ACTION_SET_FLAG) intent.setPackage(RECEIVING_PACKAGE) @@ -90,7 +120,7 @@ class FlagManager constructor(val context: Context) : FlagReader { return intent } - fun keyToSettingsPrefix(key: Int): String? { + fun keyToSettingsPrefix(key: Int): String { return SETTINGS_PREFIX + "/" + key } @@ -101,6 +131,22 @@ class FlagManager constructor(val context: Context) : FlagReader { false } } + + inner class SettingsObserver : ContentObserver(handler) { + override fun onChange(selfChange: Boolean, uri: Uri?) { + if (uri == null) { + return + } + val parts = uri.pathSegments + val idStr = parts[parts.size - 1] + try { + val id = idStr.toInt() + listeners.forEach { l -> l.onFlagChanged(id) } + } catch (e: NumberFormatException) { + // no-op + } + } + } } class InvalidFlagStorageException : Exception("Data found but is invalid")
\ No newline at end of file diff --git a/packages/SystemUI/shared/src/com/android/systemui/flags/FlagReader.kt b/packages/SystemUI/shared/src/com/android/systemui/flags/FlagReader.kt index ef8ec37d7cda..ee6dea5364f4 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/flags/FlagReader.kt +++ b/packages/SystemUI/shared/src/com/android/systemui/flags/FlagReader.kt @@ -31,7 +31,7 @@ interface FlagReader { fun removeListener(listener: Listener) {} /** A simple listener to be alerted when a flag changes. */ - interface Listener { + fun interface Listener { /** */ fun onFlagChanged(id: Int) } diff --git a/packages/SystemUI/src-debug/com/android/systemui/flags/FeatureFlagManager.java b/packages/SystemUI/src-debug/com/android/systemui/flags/FeatureFlagManager.java index 376812394801..9311966f82f2 100644 --- a/packages/SystemUI/src-debug/com/android/systemui/flags/FeatureFlagManager.java +++ b/packages/SystemUI/src-debug/com/android/systemui/flags/FeatureFlagManager.java @@ -129,10 +129,14 @@ public class FeatureFlagManager implements FlagReader, FlagWriter, Dumpable { } @Override - public void addListener(Listener run) {} + public void addListener(Listener run) { + mFlagManager.addListener(run); + } @Override - public void removeListener(Listener run) {} + public void removeListener(Listener run) { + mFlagManager.removeListener(run); + } private void restartSystemUI() { Log.i(TAG, "Restarting SystemUI"); diff --git a/packages/SystemUI/src-debug/com/android/systemui/flags/FlagsModule.kt b/packages/SystemUI/src-debug/com/android/systemui/flags/FlagsModule.kt index 0fe0fee694b9..bee4d7d3b411 100644 --- a/packages/SystemUI/src-debug/com/android/systemui/flags/FlagsModule.kt +++ b/packages/SystemUI/src-debug/com/android/systemui/flags/FlagsModule.kt @@ -17,14 +17,19 @@ package com.android.systemui.flags import android.content.Context +import android.os.Handler +import com.android.systemui.dagger.qualifiers.Main +import com.android.systemui.util.settings.SettingsUtilModule import dagger.Module import dagger.Provides -@Module +@Module(includes = [ + SettingsUtilModule::class +]) object FlagsModule { @JvmStatic @Provides - fun provideFlagManager(context: Context): FlagManager { - return FlagManager(context) + fun provideFlagManager(context: Context, @Main handler: Handler): FlagManager { + return FlagManager(context, handler) } }
\ No newline at end of file |