Merge "Add support for flag change listeners library." into sc-v2-dev am: c61d506a90 am: 6a9f7f79f6

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/16182385

Change-Id: Ic4e7ec1b6b80e6690d06c50e66751ee4162d48ae
This commit is contained in:
Dave Mankoff
2021-11-04 20:13:05 +00:00
committed by Automerger Merge Worker
7 changed files with 66 additions and 11 deletions

View File

@@ -83,8 +83,7 @@ android_library {
"src/**/*.kt",
"src/**/*.java",
"src/**/I*.aidl",
"src-release/**/*.kt",
"src-release/**/*.java",
":ReleaseJavaFiles",
],
product_variables: {
debuggable: {

View File

@@ -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.

View File

@@ -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",

View File

@@ -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")

View File

@@ -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)
}

View File

@@ -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");

View File

@@ -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)
}
}