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

Commit c61d506a authored by Dave Mankoff's avatar Dave Mankoff Committed by Android (Google) Code Review
Browse files

Merge "Add support for flag change listeners library." into sc-v2-dev

parents 0100abaf 72a50029
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