blob: a8f05bbd56005e8295ba9dfdbfe95805b6f7d3c4 [file] [log] [blame]
rnlee81d32602021-07-27 13:24:07 -07001/*
2 * Copyright (C) 2021 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "FlagManager.h"
18
19#include <SurfaceFlingerProperties.sysprop.h>
20#include <android-base/parsebool.h>
21#include <android-base/parseint.h>
Leon Scroggins IIIa37ca992022-02-02 18:08:20 -050022#include <android-base/properties.h>
rnlee81d32602021-07-27 13:24:07 -070023#include <android-base/stringprintf.h>
24#include <log/log.h>
Leon Scroggins IIIa37ca992022-02-02 18:08:20 -050025#include <renderengine/RenderEngine.h>
rnlee81d32602021-07-27 13:24:07 -070026#include <server_configurable_flags/get_flags.h>
27#include <cinttypes>
28
Ady Abrahamd6d80162023-10-23 12:57:41 -070029#include <com_android_graphics_surfaceflinger_flags.h>
30
rnlee81d32602021-07-27 13:24:07 -070031namespace android {
Ady Abrahamd6d80162023-10-23 12:57:41 -070032using namespace com::android::graphics::surfaceflinger;
33
rnlee81d32602021-07-27 13:24:07 -070034static constexpr const char* kExperimentNamespace = "surface_flinger_native_boot";
rnlee81d32602021-07-27 13:24:07 -070035
Ady Abraham53b0c492023-10-23 11:47:14 -070036std::unique_ptr<FlagManager> FlagManager::mInstance;
37std::once_flag FlagManager::mOnce;
38
39FlagManager::FlagManager(ConstructorTag) {}
rnlee81d32602021-07-27 13:24:07 -070040FlagManager::~FlagManager() = default;
41
rnlee81d32602021-07-27 13:24:07 -070042namespace {
Ady Abrahamc589dc42023-10-26 16:20:53 -070043std::optional<bool> parseBool(const char* str) {
rnlee81d32602021-07-27 13:24:07 -070044 base::ParseBoolResult parseResult = base::ParseBool(str);
45 switch (parseResult) {
46 case base::ParseBoolResult::kTrue:
47 return std::make_optional(true);
48 case base::ParseBoolResult::kFalse:
49 return std::make_optional(false);
50 case base::ParseBoolResult::kError:
51 return std::nullopt;
52 }
53}
Ady Abrahamc589dc42023-10-26 16:20:53 -070054
Ady Abrahamd6d80162023-10-23 12:57:41 -070055bool getFlagValue(std::function<bool()> getter, std::optional<bool> overrideValue) {
56 if (overrideValue.has_value()) {
57 return *overrideValue;
58 }
59
60 return getter();
61}
62
Ady Abrahamc589dc42023-10-26 16:20:53 -070063void dumpFlag(std::string& result, const char* name, std::function<bool()> getter) {
64 base::StringAppendF(&result, "%s: %s\n", name, getter() ? "true" : "false");
65}
66
rnlee81d32602021-07-27 13:24:07 -070067} // namespace
68
Ady Abrahamc589dc42023-10-26 16:20:53 -070069const FlagManager& FlagManager::getInstance() {
70 return getMutableInstance();
rnlee81d32602021-07-27 13:24:07 -070071}
72
Ady Abrahamc589dc42023-10-26 16:20:53 -070073FlagManager& FlagManager::getMutableInstance() {
74 std::call_once(mOnce, [&] {
75 LOG_ALWAYS_FATAL_IF(mInstance, "Instance already created");
76 mInstance = std::make_unique<FlagManager>(ConstructorTag{});
77 });
78
79 return *mInstance;
80}
81
82void FlagManager::markBootCompleted() {
83 mBootCompleted = true;
84}
85
Ady Abrahamd6d80162023-10-23 12:57:41 -070086void FlagManager::setUnitTestMode() {
87 mUnitTestMode = true;
88
89 // Also set boot completed as we don't really care about it in unit testing
90 mBootCompleted = true;
91}
92
Ady Abrahamc589dc42023-10-26 16:20:53 -070093void FlagManager::dump(std::string& result) const {
Ady Abrahamd6d80162023-10-23 12:57:41 -070094#define DUMP_FLAG(name) dumpFlag(result, #name, std::bind(&FlagManager::name, this))
Ady Abrahamc589dc42023-10-26 16:20:53 -070095
96 base::StringAppendF(&result, "FlagManager values: \n");
97 DUMP_FLAG(use_adpf_cpu_hint);
98 DUMP_FLAG(use_skia_tracing);
Ady Abrahamd6d80162023-10-23 12:57:41 -070099 DUMP_FLAG(connected_display);
100 DUMP_FLAG(dont_skip_on_early);
101 DUMP_FLAG(enable_small_area_detection);
102 DUMP_FLAG(misc1);
103 DUMP_FLAG(late_boot_misc2);
104 DUMP_FLAG(vrr_config);
Ady Abrahamc589dc42023-10-26 16:20:53 -0700105
106#undef DUMP_FLAG
107}
108
109std::optional<bool> FlagManager::getBoolProperty(const char* property) const {
110 return parseBool(base::GetProperty(property, "").c_str());
111}
112
113bool FlagManager::getServerConfigurableFlag(const char* experimentFlagName) const {
114 const auto value = server_configurable_flags::GetServerConfigurableFlag(kExperimentNamespace,
115 experimentFlagName, "");
116 const auto res = parseBool(value.c_str());
117 return res.has_value() && res.value();
118}
119
Ady Abrahamd6d80162023-10-23 12:57:41 -0700120#define FLAG_MANAGER_LEGACY_SERVER_FLAG(name, syspropOverride, serverFlagName) \
Ady Abrahamc589dc42023-10-26 16:20:53 -0700121 bool FlagManager::name() const { \
122 LOG_ALWAYS_FATAL_IF(!mBootCompleted, \
123 "Can't read %s before boot completed as it is server writable", \
124 __func__); \
125 const auto debugOverride = getBoolProperty(syspropOverride); \
126 if (debugOverride.has_value()) return debugOverride.value(); \
127 return getServerConfigurableFlag(serverFlagName); \
rnlee81d32602021-07-27 13:24:07 -0700128 }
rnlee81d32602021-07-27 13:24:07 -0700129
Ady Abrahamd6d80162023-10-23 12:57:41 -0700130#define FLAG_MANAGER_FLAG_INTERNAL(name, syspropOverride, checkForBootCompleted) \
131 bool FlagManager::name() const { \
132 if (checkForBootCompleted) { \
133 LOG_ALWAYS_FATAL_IF(!mBootCompleted, \
134 "Can't read %s before boot completed as it is server writable", \
135 __func__); \
136 } \
137 static std::optional<bool> debugOverride = getBoolProperty(syspropOverride); \
138 static bool value = getFlagValue([] { return flags::name(); }, debugOverride); \
139 if (mUnitTestMode) { \
140 /* \
141 * When testing, we don't want to rely on the cached values stored in the static \
142 * variables. \
143 */ \
144 debugOverride = getBoolProperty(syspropOverride); \
145 value = getFlagValue([] { return flags::name(); }, debugOverride); \
146 } \
147 return value; \
148 }
Matt Buckleyd23c7962021-09-21 20:43:00 +0000149
Ady Abrahamd6d80162023-10-23 12:57:41 -0700150#define FLAG_MANAGER_SERVER_FLAG(name, syspropOverride) \
151 FLAG_MANAGER_FLAG_INTERNAL(name, syspropOverride, true)
152
153#define FLAG_MANAGER_READ_ONLY_FLAG(name, syspropOverride) \
154 FLAG_MANAGER_FLAG_INTERNAL(name, syspropOverride, false)
155
156/// Legacy server flags ///
157FLAG_MANAGER_LEGACY_SERVER_FLAG(test_flag, "", "")
158FLAG_MANAGER_LEGACY_SERVER_FLAG(use_adpf_cpu_hint, "debug.sf.enable_adpf_cpu_hint",
159 "AdpfFeature__adpf_cpu_hint")
160FLAG_MANAGER_LEGACY_SERVER_FLAG(use_skia_tracing, PROPERTY_SKIA_ATRACE_ENABLED,
161 "SkiaTracingFeature__use_skia_tracing")
162
163/// Trunk stable readonly flags ///
164FLAG_MANAGER_READ_ONLY_FLAG(connected_display, "")
165FLAG_MANAGER_READ_ONLY_FLAG(enable_small_area_detection, "")
166FLAG_MANAGER_READ_ONLY_FLAG(misc1, "")
167FLAG_MANAGER_READ_ONLY_FLAG(vrr_config, "debug.sf.enable_vrr_config")
168
169/// Trunk stable server flags ///
170FLAG_MANAGER_SERVER_FLAG(late_boot_misc2, "")
171
172/// Exceptions ///
173bool FlagManager::dont_skip_on_early() const {
174 // Even though this is a server writable flag, we do call it before boot completed, but that's
175 // fine since the decision is done per frame. We can't do caching though.
176 return flags::dont_skip_on_early();
177}
Leon Scroggins IIIa37ca992022-02-02 18:08:20 -0500178
rnlee81d32602021-07-27 13:24:07 -0700179} // namespace android