blob: 5067c0eeeaab03e00b58d7f99a1d52b05242cc83 [file] [log] [blame]
/*
* 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)
}
}