Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 72a50029 authored by Dave Mankoff's avatar Dave Mankoff
Browse files

Add support for flag change listeners library.

Bug: 203548827
Test: manual
Change-Id: I6f989e89a98c7c6643af762eb0263f81ce584dfa
parent 1a934e9a
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -83,8 +83,7 @@ android_library {
        "src/**/*.kt",
        "src/**/*.java",
        "src/**/I*.aidl",
        "src-release/**/*.kt",
        "src-release/**/*.java",
        ":ReleaseJavaFiles",
    ],
    product_variables: {
        debuggable: {
+1 −0
Original line number Diff line number Diff line

# 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.
+1 −1
Original line number Diff line number Diff line
@@ -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",
+48 −2
Original line number Diff line number Diff line
@@ -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
+1 −1
Original line number Diff line number Diff line
@@ -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)
    }
Loading