blob: 5bbdfe91e665fd3532d537db4aa3586e32267a52 [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);
Brian Johnson8c144002023-10-30 15:47:44 -0700105 DUMP_FLAG(hotplug2);
Ady Abrahamc589dc42023-10-26 16:20:53 -0700106
107#undef DUMP_FLAG
108}
109
110std::optional<bool> FlagManager::getBoolProperty(const char* property) const {
111 return parseBool(base::GetProperty(property, "").c_str());
112}
113
114bool FlagManager::getServerConfigurableFlag(const char* experimentFlagName) const {
115 const auto value = server_configurable_flags::GetServerConfigurableFlag(kExperimentNamespace,
116 experimentFlagName, "");
117 const auto res = parseBool(value.c_str());
118 return res.has_value() && res.value();
119}
120
Ady Abrahamd6d80162023-10-23 12:57:41 -0700121#define FLAG_MANAGER_LEGACY_SERVER_FLAG(name, syspropOverride, serverFlagName) \
Ady Abrahamc589dc42023-10-26 16:20:53 -0700122 bool FlagManager::name() const { \
123 LOG_ALWAYS_FATAL_IF(!mBootCompleted, \
124 "Can't read %s before boot completed as it is server writable", \
125 __func__); \
126 const auto debugOverride = getBoolProperty(syspropOverride); \
127 if (debugOverride.has_value()) return debugOverride.value(); \
128 return getServerConfigurableFlag(serverFlagName); \
rnlee81d32602021-07-27 13:24:07 -0700129 }
rnlee81d32602021-07-27 13:24:07 -0700130
Ady Abrahamd6d80162023-10-23 12:57:41 -0700131#define FLAG_MANAGER_FLAG_INTERNAL(name, syspropOverride, checkForBootCompleted) \
132 bool FlagManager::name() const { \
133 if (checkForBootCompleted) { \
134 LOG_ALWAYS_FATAL_IF(!mBootCompleted, \
135 "Can't read %s before boot completed as it is server writable", \
136 __func__); \
137 } \
138 static std::optional<bool> debugOverride = getBoolProperty(syspropOverride); \
139 static bool value = getFlagValue([] { return flags::name(); }, debugOverride); \
140 if (mUnitTestMode) { \
141 /* \
142 * When testing, we don't want to rely on the cached values stored in the static \
143 * variables. \
144 */ \
145 debugOverride = getBoolProperty(syspropOverride); \
146 value = getFlagValue([] { return flags::name(); }, debugOverride); \
147 } \
148 return value; \
149 }
Matt Buckleyd23c7962021-09-21 20:43:00 +0000150
Ady Abrahamd6d80162023-10-23 12:57:41 -0700151#define FLAG_MANAGER_SERVER_FLAG(name, syspropOverride) \
152 FLAG_MANAGER_FLAG_INTERNAL(name, syspropOverride, true)
153
154#define FLAG_MANAGER_READ_ONLY_FLAG(name, syspropOverride) \
155 FLAG_MANAGER_FLAG_INTERNAL(name, syspropOverride, false)
156
157/// Legacy server flags ///
158FLAG_MANAGER_LEGACY_SERVER_FLAG(test_flag, "", "")
159FLAG_MANAGER_LEGACY_SERVER_FLAG(use_adpf_cpu_hint, "debug.sf.enable_adpf_cpu_hint",
160 "AdpfFeature__adpf_cpu_hint")
161FLAG_MANAGER_LEGACY_SERVER_FLAG(use_skia_tracing, PROPERTY_SKIA_ATRACE_ENABLED,
162 "SkiaTracingFeature__use_skia_tracing")
163
164/// Trunk stable readonly flags ///
165FLAG_MANAGER_READ_ONLY_FLAG(connected_display, "")
166FLAG_MANAGER_READ_ONLY_FLAG(enable_small_area_detection, "")
167FLAG_MANAGER_READ_ONLY_FLAG(misc1, "")
168FLAG_MANAGER_READ_ONLY_FLAG(vrr_config, "debug.sf.enable_vrr_config")
Brian Johnson8c144002023-10-30 15:47:44 -0700169FLAG_MANAGER_READ_ONLY_FLAG(hotplug2, "")
Ady Abrahamd6d80162023-10-23 12:57:41 -0700170
171/// Trunk stable server flags ///
172FLAG_MANAGER_SERVER_FLAG(late_boot_misc2, "")
173
174/// Exceptions ///
175bool FlagManager::dont_skip_on_early() const {
176 // Even though this is a server writable flag, we do call it before boot completed, but that's
177 // fine since the decision is done per frame. We can't do caching though.
178 return flags::dont_skip_on_early();
179}
Leon Scroggins IIIa37ca992022-02-02 18:08:20 -0500180
rnlee81d32602021-07-27 13:24:07 -0700181} // namespace android