diff options
8 files changed, 270 insertions, 1 deletions
@@ -31,13 +31,34 @@ license { ], } +filegroup { + name: "ReleaseSources", + srcs: [ + "java/src-release/**/*.kt", + ], +} + +filegroup { + name: "DebugSources", + srcs: [ + "java/src-debug/**/*.kt", + ], +} + android_library { name: "IntentResolver-core", min_sdk_version: "current", srcs: [ "java/src/**/*.java", "java/src/**/*.kt", + ":ReleaseSources", ], + product_variables: { + debuggable: { + srcs: [":DebugSources"], + exclude_srcs: [":ReleaseSources"], + } + }, resource_dirs: [ "java/res", ], @@ -58,10 +79,11 @@ android_library { "kotlinx-coroutines-android", "//external/kotlinc:kotlin-annotations", "guava", + "SystemUIFlagsLib", ], lint: { - strict_updatability_linting: true, + strict_updatability_linting: false, }, } diff --git a/java/src-debug/com/android/intentresolver/flags/DebugFeatureFlagRepository.kt b/java/src-debug/com/android/intentresolver/flags/DebugFeatureFlagRepository.kt new file mode 100644 index 00000000..5067c0ee --- /dev/null +++ b/java/src-debug/com/android/intentresolver/flags/DebugFeatureFlagRepository.kt @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.intentresolver.flags + +import android.util.SparseBooleanArray +import androidx.annotation.GuardedBy +import com.android.systemui.flags.BooleanFlag +import com.android.systemui.flags.FlagManager +import com.android.systemui.flags.ReleasedFlag +import com.android.systemui.flags.UnreleasedFlag +import javax.annotation.concurrent.ThreadSafe + +@ThreadSafe +internal class DebugFeatureFlagRepository( + private val flagManager: FlagManager, + private val deviceConfig: DeviceConfigProxy, +) : FeatureFlagRepository { + @GuardedBy("self") + private val cache = hashMapOf<String, Boolean>() + + override fun isEnabled(flag: UnreleasedFlag): Boolean = isFlagEnabled(flag) + + override fun isEnabled(flag: ReleasedFlag): Boolean = isFlagEnabled(flag) + + private fun isFlagEnabled(flag: BooleanFlag): Boolean { + synchronized(cache) { + cache[flag.name]?.let { return it } + } + val flagValue = readFlagValue(flag) + return synchronized(cache) { + // the first read saved in the cache wins + cache.getOrPut(flag.name) { flagValue } + } + } + + private fun readFlagValue(flag: BooleanFlag): Boolean { + val localOverride = runCatching { + flagManager.isEnabled(flag.name) + }.getOrDefault(null) + val remoteOverride = deviceConfig.isEnabled(flag) + + // Only check for teamfood if the default is false + // and there is no server override. + if (remoteOverride == null + && !flag.default + && localOverride == null + && !flag.isTeamfoodFlag + && flag.teamfood + ) { + return flagManager.isTeamfoodEnabled + } + return localOverride ?: remoteOverride ?: flag.default + } + + companion object { + /** keep in sync with [com.android.systemui.flags.Flags] */ + private const val TEAMFOOD_FLAG_NAME = "teamfood" + + private val BooleanFlag.isTeamfoodFlag: Boolean + get() = name == TEAMFOOD_FLAG_NAME + + private val FlagManager.isTeamfoodEnabled: Boolean + get() = runCatching { + isEnabled(TEAMFOOD_FLAG_NAME) ?: false + }.getOrDefault(false) + } +} diff --git a/java/src-debug/com/android/intentresolver/flags/FeatureFlagRepositoryFactory.kt b/java/src-debug/com/android/intentresolver/flags/FeatureFlagRepositoryFactory.kt new file mode 100644 index 00000000..4ddb0447 --- /dev/null +++ b/java/src-debug/com/android/intentresolver/flags/FeatureFlagRepositoryFactory.kt @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.intentresolver.flags + +import android.content.Context +import android.os.Handler +import android.os.Looper +import com.android.systemui.flags.FlagManager + +class FeatureFlagRepositoryFactory { + fun create(context: Context): FeatureFlagRepository = + DebugFeatureFlagRepository( + FlagManager(context, Handler(Looper.getMainLooper())), + DeviceConfigProxy(), + ) +} diff --git a/java/src-release/com/android/intentresolver/flags/FeatureFlagRepositoryFactory.kt b/java/src-release/com/android/intentresolver/flags/FeatureFlagRepositoryFactory.kt new file mode 100644 index 00000000..6bf7579e --- /dev/null +++ b/java/src-release/com/android/intentresolver/flags/FeatureFlagRepositoryFactory.kt @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.intentresolver.flags + +import android.content.Context + +class FeatureFlagRepositoryFactory { + fun create(context: Context): FeatureFlagRepository = + ReleaseFeatureFlagRepository(DeviceConfigProxy()) +} diff --git a/java/src-release/com/android/intentresolver/flags/ReleaseFeatureFlagRepository.kt b/java/src-release/com/android/intentresolver/flags/ReleaseFeatureFlagRepository.kt new file mode 100644 index 00000000..f9fa2c6a --- /dev/null +++ b/java/src-release/com/android/intentresolver/flags/ReleaseFeatureFlagRepository.kt @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.intentresolver.flags + +import com.android.systemui.flags.ReleasedFlag +import com.android.systemui.flags.UnreleasedFlag +import javax.annotation.concurrent.ThreadSafe + +@ThreadSafe +internal class ReleaseFeatureFlagRepository( + private val deviceConfig: DeviceConfigProxy, +) : FeatureFlagRepository { + override fun isEnabled(flag: UnreleasedFlag): Boolean = flag.default + + override fun isEnabled(flag: ReleasedFlag): Boolean = + deviceConfig.isEnabled(flag) ?: flag.default +} diff --git a/java/src/com/android/intentresolver/flags/DeviceConfigProxy.kt b/java/src/com/android/intentresolver/flags/DeviceConfigProxy.kt new file mode 100644 index 00000000..ac782471 --- /dev/null +++ b/java/src/com/android/intentresolver/flags/DeviceConfigProxy.kt @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.intentresolver.flags + +import android.provider.DeviceConfig +import com.android.systemui.flags.ParcelableFlag + +internal class DeviceConfigProxy { + fun isEnabled(flag: ParcelableFlag<Boolean>): Boolean? { + return runCatching { + DeviceConfig.getBoolean(flag.namespace, flag.name, flag.default) + }.getOrDefault(null) + } +} diff --git a/java/src/com/android/intentresolver/flags/FeatureFlagRepository.kt b/java/src/com/android/intentresolver/flags/FeatureFlagRepository.kt new file mode 100644 index 00000000..5b5d769c --- /dev/null +++ b/java/src/com/android/intentresolver/flags/FeatureFlagRepository.kt @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.intentresolver.flags + +import com.android.systemui.flags.ReleasedFlag +import com.android.systemui.flags.UnreleasedFlag + +interface FeatureFlagRepository { + fun isEnabled(flag: UnreleasedFlag): Boolean + fun isEnabled(flag: ReleasedFlag): Boolean +} diff --git a/java/src/com/android/intentresolver/flags/Flags.kt b/java/src/com/android/intentresolver/flags/Flags.kt new file mode 100644 index 00000000..c9271a6a --- /dev/null +++ b/java/src/com/android/intentresolver/flags/Flags.kt @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.intentresolver.flags + +import com.android.systemui.flags.UnreleasedFlag + +// keep in sync with com.android.systemui.flags.Flags to make the flags available in the +// flag flipper app (see go/sysui-flags) +object Flags { + @JvmField + val SHARESHEET_CUSTOM_ACTIONS = UnreleasedFlag( + id = 1501, name = "sharesheet_custom_actions", namespace = "systemui", teamfood = false + ) +} |