Merge "Communicate flags from systemui async" into sc-v2-dev am: c3ef628c75
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/16200718 Change-Id: Ib5a429f951a65f3f277baed4e21a8c18ed55ba69
This commit is contained in:
@@ -62,6 +62,7 @@ java_library {
|
|||||||
srcs: [
|
srcs: [
|
||||||
"src/com/android/systemui/flags/Flag.kt",
|
"src/com/android/systemui/flags/Flag.kt",
|
||||||
],
|
],
|
||||||
|
include_srcs: true,
|
||||||
static_kotlin_stdlib: false,
|
static_kotlin_stdlib: false,
|
||||||
java_version: "1.8",
|
java_version: "1.8",
|
||||||
min_sdk_version: "current",
|
min_sdk_version: "current",
|
||||||
@@ -74,11 +75,11 @@ java_library {
|
|||||||
],
|
],
|
||||||
static_kotlin_stdlib: false,
|
static_kotlin_stdlib: false,
|
||||||
libs: [
|
libs: [
|
||||||
|
"SystemUI-flags",
|
||||||
"androidx.concurrent_concurrent-futures",
|
"androidx.concurrent_concurrent-futures",
|
||||||
],
|
],
|
||||||
static_libs: [
|
static_libs: [
|
||||||
"SystemUI-flag-types",
|
"SystemUI-flag-types",
|
||||||
"SystemUI-flags",
|
|
||||||
],
|
],
|
||||||
java_version: "1.8",
|
java_version: "1.8",
|
||||||
min_sdk_version: "current",
|
min_sdk_version: "current",
|
||||||
|
|||||||
@@ -16,37 +16,157 @@
|
|||||||
|
|
||||||
package com.android.systemui.flags
|
package com.android.systemui.flags
|
||||||
|
|
||||||
interface Flag<T> {
|
import android.os.Parcel
|
||||||
|
import android.os.Parcelable
|
||||||
|
|
||||||
|
interface Flag<T> : Parcelable {
|
||||||
val id: Int
|
val id: Int
|
||||||
val default: T
|
val default: T
|
||||||
|
|
||||||
|
override fun describeContents() = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Consider using the "parcelize" kotlin library.
|
||||||
|
|
||||||
data class BooleanFlag @JvmOverloads constructor(
|
data class BooleanFlag @JvmOverloads constructor(
|
||||||
override val id: Int,
|
override val id: Int,
|
||||||
override val default: Boolean = false
|
override val default: Boolean = false
|
||||||
) : Flag<Boolean>
|
) : Flag<Boolean> {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@JvmField
|
||||||
|
val CREATOR = object : Parcelable.Creator<BooleanFlag> {
|
||||||
|
override fun createFromParcel(parcel: Parcel) = BooleanFlag(parcel)
|
||||||
|
override fun newArray(size: Int) = arrayOfNulls<BooleanFlag>(size)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private constructor(parcel: Parcel) : this(
|
||||||
|
id = parcel.readInt(),
|
||||||
|
default = parcel.readBoolean()
|
||||||
|
)
|
||||||
|
|
||||||
|
override fun writeToParcel(parcel: Parcel, flags: Int) {
|
||||||
|
parcel.writeInt(id)
|
||||||
|
parcel.writeBoolean(default)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
data class StringFlag @JvmOverloads constructor(
|
data class StringFlag @JvmOverloads constructor(
|
||||||
override val id: Int,
|
override val id: Int,
|
||||||
override val default: String = ""
|
override val default: String = ""
|
||||||
) : Flag<String>
|
) : Flag<String> {
|
||||||
|
companion object {
|
||||||
|
@JvmField
|
||||||
|
val CREATOR = object : Parcelable.Creator<StringFlag> {
|
||||||
|
override fun createFromParcel(parcel: Parcel) = StringFlag(parcel)
|
||||||
|
override fun newArray(size: Int) = arrayOfNulls<StringFlag>(size)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private constructor(parcel: Parcel) : this(
|
||||||
|
id = parcel.readInt(),
|
||||||
|
default = parcel.readString() ?: ""
|
||||||
|
)
|
||||||
|
|
||||||
|
override fun writeToParcel(parcel: Parcel, flags: Int) {
|
||||||
|
parcel.writeInt(id)
|
||||||
|
parcel.writeString(default)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
data class IntFlag @JvmOverloads constructor(
|
data class IntFlag @JvmOverloads constructor(
|
||||||
override val id: Int,
|
override val id: Int,
|
||||||
override val default: Int = 0
|
override val default: Int = 0
|
||||||
) : Flag<Int>
|
) : Flag<Int> {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@JvmField
|
||||||
|
val CREATOR = object : Parcelable.Creator<IntFlag> {
|
||||||
|
override fun createFromParcel(parcel: Parcel) = IntFlag(parcel)
|
||||||
|
override fun newArray(size: Int) = arrayOfNulls<IntFlag>(size)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private constructor(parcel: Parcel) : this(
|
||||||
|
id = parcel.readInt(),
|
||||||
|
default = parcel.readInt()
|
||||||
|
)
|
||||||
|
|
||||||
|
override fun writeToParcel(parcel: Parcel, flags: Int) {
|
||||||
|
parcel.writeInt(id)
|
||||||
|
parcel.writeInt(default)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
data class LongFlag @JvmOverloads constructor(
|
data class LongFlag @JvmOverloads constructor(
|
||||||
override val id: Int,
|
override val id: Int,
|
||||||
override val default: Long = 0
|
override val default: Long = 0
|
||||||
) : Flag<Long>
|
) : Flag<Long> {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@JvmField
|
||||||
|
val CREATOR = object : Parcelable.Creator<LongFlag> {
|
||||||
|
override fun createFromParcel(parcel: Parcel) = LongFlag(parcel)
|
||||||
|
override fun newArray(size: Int) = arrayOfNulls<LongFlag>(size)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private constructor(parcel: Parcel) : this(
|
||||||
|
id = parcel.readInt(),
|
||||||
|
default = parcel.readLong()
|
||||||
|
)
|
||||||
|
|
||||||
|
override fun writeToParcel(parcel: Parcel, flags: Int) {
|
||||||
|
parcel.writeInt(id)
|
||||||
|
parcel.writeLong(default)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
data class FloatFlag @JvmOverloads constructor(
|
data class FloatFlag @JvmOverloads constructor(
|
||||||
override val id: Int,
|
override val id: Int,
|
||||||
override val default: Float = 0f
|
override val default: Float = 0f
|
||||||
) : Flag<Float>
|
) : Flag<Float> {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@JvmField
|
||||||
|
val CREATOR = object : Parcelable.Creator<FloatFlag> {
|
||||||
|
override fun createFromParcel(parcel: Parcel) = FloatFlag(parcel)
|
||||||
|
override fun newArray(size: Int) = arrayOfNulls<FloatFlag>(size)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private constructor(parcel: Parcel) : this(
|
||||||
|
id = parcel.readInt(),
|
||||||
|
default = parcel.readFloat()
|
||||||
|
)
|
||||||
|
|
||||||
|
override fun writeToParcel(parcel: Parcel, flags: Int) {
|
||||||
|
parcel.writeInt(id)
|
||||||
|
parcel.writeFloat(default)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
data class DoubleFlag @JvmOverloads constructor(
|
data class DoubleFlag @JvmOverloads constructor(
|
||||||
override val id: Int,
|
override val id: Int,
|
||||||
override val default: Double = 0.0
|
override val default: Double = 0.0
|
||||||
) : Flag<Double>
|
) : Flag<Double> {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@JvmField
|
||||||
|
val CREATOR = object : Parcelable.Creator<DoubleFlag> {
|
||||||
|
override fun createFromParcel(parcel: Parcel) = DoubleFlag(parcel)
|
||||||
|
override fun newArray(size: Int) = arrayOfNulls<DoubleFlag>(size)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private constructor(parcel: Parcel) : this(
|
||||||
|
id = parcel.readInt(),
|
||||||
|
default = parcel.readDouble()
|
||||||
|
)
|
||||||
|
|
||||||
|
override fun writeToParcel(parcel: Parcel, flags: Int) {
|
||||||
|
parcel.writeInt(id)
|
||||||
|
parcel.writeDouble(default)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,10 +16,13 @@
|
|||||||
|
|
||||||
package com.android.systemui.flags
|
package com.android.systemui.flags
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
|
import android.content.BroadcastReceiver
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.database.ContentObserver
|
import android.database.ContentObserver
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
|
import android.os.Bundle
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.provider.Settings
|
import android.provider.Settings
|
||||||
import androidx.concurrent.futures.CallbackToFutureAdapter
|
import androidx.concurrent.futures.CallbackToFutureAdapter
|
||||||
@@ -34,10 +37,12 @@ class FlagManager constructor(
|
|||||||
companion object {
|
companion object {
|
||||||
const val RECEIVING_PACKAGE = "com.android.systemui"
|
const val RECEIVING_PACKAGE = "com.android.systemui"
|
||||||
const val ACTION_SET_FLAG = "com.android.systemui.action.SET_FLAG"
|
const val ACTION_SET_FLAG = "com.android.systemui.action.SET_FLAG"
|
||||||
|
const val ACTION_GET_FLAGS = "com.android.systemui.action.GET_FLAGS"
|
||||||
const val FLAGS_PERMISSION = "com.android.systemui.permission.FLAGS"
|
const val FLAGS_PERMISSION = "com.android.systemui.permission.FLAGS"
|
||||||
const val FIELD_ID = "id"
|
const val FIELD_ID = "id"
|
||||||
const val FIELD_VALUE = "value"
|
const val FIELD_VALUE = "value"
|
||||||
const val FIELD_TYPE = "type"
|
const val FIELD_TYPE = "type"
|
||||||
|
const val FIELD_FLAGS = "flags"
|
||||||
const val TYPE_BOOLEAN = "boolean"
|
const val TYPE_BOOLEAN = "boolean"
|
||||||
private const val SETTINGS_PREFIX = "systemui/flags"
|
private const val SETTINGS_PREFIX = "systemui/flags"
|
||||||
}
|
}
|
||||||
@@ -46,14 +51,26 @@ class FlagManager constructor(
|
|||||||
private val settingsObserver: ContentObserver = SettingsObserver()
|
private val settingsObserver: ContentObserver = SettingsObserver()
|
||||||
|
|
||||||
fun getFlagsFuture(): ListenableFuture<Collection<Flag<*>>> {
|
fun getFlagsFuture(): ListenableFuture<Collection<Flag<*>>> {
|
||||||
val knownFlagMap = Flags.collectFlags()
|
val intent = Intent(ACTION_GET_FLAGS)
|
||||||
// Possible todo in the future: query systemui async to actually get the known flag ids.
|
intent.setPackage(RECEIVING_PACKAGE)
|
||||||
return CallbackToFutureAdapter.getFuture(
|
|
||||||
CallbackToFutureAdapter.Resolver {
|
return CallbackToFutureAdapter.getFuture {
|
||||||
completer: CallbackToFutureAdapter.Completer<Collection<Flag<*>>> ->
|
completer: CallbackToFutureAdapter.Completer<Any?> ->
|
||||||
completer.set(knownFlagMap.values as Collection<Flag<*>>)
|
context.sendOrderedBroadcast(intent, null,
|
||||||
"Retrieving Flags"
|
object : BroadcastReceiver() {
|
||||||
})
|
override fun onReceive(context: Context, intent: Intent) {
|
||||||
|
val extras: Bundle? = getResultExtras(false)
|
||||||
|
val listOfFlags: java.util.ArrayList<Flag<*>>? =
|
||||||
|
extras?.getParcelableArrayList(FIELD_FLAGS)
|
||||||
|
if (listOfFlags != null) {
|
||||||
|
completer.set(listOfFlags)
|
||||||
|
} else {
|
||||||
|
completer.setException(NoFlagResultsException())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, null, Activity.RESULT_OK, "extra data", null)
|
||||||
|
"QueryingFlags"
|
||||||
|
} as ListenableFuture<Collection<Flag<*>>>
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setFlagValue(id: Int, enabled: Boolean) {
|
fun setFlagValue(id: Int, enabled: Boolean) {
|
||||||
@@ -149,4 +166,7 @@ class FlagManager constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class InvalidFlagStorageException : Exception("Data found but is invalid")
|
class InvalidFlagStorageException : Exception("Data found but is invalid")
|
||||||
|
|
||||||
|
class NoFlagResultsException : Exception(
|
||||||
|
"SystemUI failed to communicate its flags back successfully")
|
||||||
@@ -16,10 +16,11 @@
|
|||||||
|
|
||||||
package com.android.systemui.flags;
|
package com.android.systemui.flags;
|
||||||
|
|
||||||
|
import static com.android.systemui.flags.FlagManager.ACTION_GET_FLAGS;
|
||||||
import static com.android.systemui.flags.FlagManager.ACTION_SET_FLAG;
|
import static com.android.systemui.flags.FlagManager.ACTION_SET_FLAG;
|
||||||
|
import static com.android.systemui.flags.FlagManager.FIELD_FLAGS;
|
||||||
import static com.android.systemui.flags.FlagManager.FIELD_ID;
|
import static com.android.systemui.flags.FlagManager.FIELD_ID;
|
||||||
import static com.android.systemui.flags.FlagManager.FIELD_VALUE;
|
import static com.android.systemui.flags.FlagManager.FIELD_VALUE;
|
||||||
import static com.android.systemui.flags.FlagManager.FLAGS_PERMISSION;
|
|
||||||
|
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
@@ -69,8 +70,10 @@ public class FeatureFlagManager implements FlagReader, FlagWriter, Dumpable {
|
|||||||
DumpManager dumpManager) {
|
DumpManager dumpManager) {
|
||||||
mFlagManager = flagManager;
|
mFlagManager = flagManager;
|
||||||
mSecureSettings = secureSettings;
|
mSecureSettings = secureSettings;
|
||||||
IntentFilter filter = new IntentFilter(ACTION_SET_FLAG);
|
IntentFilter filter = new IntentFilter();
|
||||||
context.registerReceiver(mReceiver, filter, FLAGS_PERMISSION, null);
|
filter.addAction(ACTION_SET_FLAG);
|
||||||
|
filter.addAction(ACTION_GET_FLAGS);
|
||||||
|
context.registerReceiver(mReceiver, filter, null, null);
|
||||||
dumpManager.registerDumpable(TAG, this);
|
dumpManager.registerDumpable(TAG, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,9 +154,15 @@ public class FeatureFlagManager implements FlagReader, FlagWriter, Dumpable {
|
|||||||
if (action == null) {
|
if (action == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ACTION_SET_FLAG.equals(action)) {
|
if (ACTION_SET_FLAG.equals(action)) {
|
||||||
handleSetFlag(intent.getExtras());
|
handleSetFlag(intent.getExtras());
|
||||||
|
} else if (ACTION_GET_FLAGS.equals(action)) {
|
||||||
|
Map<Integer, Flag<?>> knownFlagMap = Flags.collectFlags();
|
||||||
|
ArrayList<Flag<?>> flags = new ArrayList<>(knownFlagMap.values());
|
||||||
|
Bundle extras = getResultExtras(true);
|
||||||
|
if (extras != null) {
|
||||||
|
extras.putParcelableArrayList(FIELD_FLAGS, flags);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user