Add cromite flags support
Add SET_CROMITE_FEATURE_ENABLED*, SET_CROMITE_FEATURE_DISABLED* and CROMITE_FEATURE macros, logic has been adapted from that found in brave. Allows flags to be defined in separate files. Activates a new cromite tab in chrome://flags with only the flags added and changed. In android added chrome://flags/cromite in the setting ui. Currently in wip
This commit is contained in:
@@ -282,6 +282,7 @@ Timezone-customization.patch
|
||||
00Disable-Service-and-Shared-workers-on-3P-iframe.patch
|
||||
00Disable-Real-Box.patch
|
||||
00Always-allow-inspect-fallback.patch
|
||||
00Add-cromite-flags-support.patch
|
||||
|
||||
00Temp-PerformanceNavigationTiming-privacy-fix.patch
|
||||
|
||||
|
||||
@@ -0,0 +1,840 @@
|
||||
From: uazo <uazo@users.noreply.github.com>
|
||||
Date: Sat, 18 Nov 2023 09:41:28 +0000
|
||||
Subject: Add cromite flags support
|
||||
|
||||
Add SET_CROMITE_FEATURE_ENABLED*, SET_CROMITE_FEATURE_DISABLED*
|
||||
and CROMITE_FEATURE macros, logic has been adapted from that found
|
||||
in brave.
|
||||
Allows flags to be defined in separate files.
|
||||
Activates a new cromite tab in chrome://flags with only the flags
|
||||
added and changed. In android added chrome://flags/cromite
|
||||
in the setting ui.
|
||||
Currently in wip
|
||||
|
||||
Need: bromite-build-utils.patch
|
||||
License: GPL-2.0-or-later - https://spdx.org/licenses/GPL-2.0-or-later.html
|
||||
---
|
||||
base/BUILD.gn | 4 +-
|
||||
base/feature_list.cc | 56 +++++++++++++
|
||||
base/feature_list.h | 84 ++++++++++++++++++-
|
||||
build/android/gyp/java_cpp_features.py | 17 ++++
|
||||
chrome/android/java/res/values/values.xml | 3 +
|
||||
.../java/res/xml/privacy_preferences.xml | 4 +
|
||||
chrome/browser/about_flags.cc | 7 ++
|
||||
.../flags/android/chrome_feature_list.cc | 1 +
|
||||
chrome/browser/ui/ui_features.cc | 1 +
|
||||
chrome/common/chrome_features.cc | 1 +
|
||||
components/flags_ui/flags_state.cc | 21 +++++
|
||||
components/flags_ui/resources/experiment.html | 7 +-
|
||||
components/flags_ui/resources/experiment.ts | 16 ++++
|
||||
components/flags_ui/resources/flags.css | 19 +++++
|
||||
components/flags_ui/resources/flags.html | 13 +++
|
||||
components/flags_ui/resources/flags.ts | 36 ++++++--
|
||||
.../flags_ui/resources/flags_browser_proxy.ts | 5 ++
|
||||
content/common/features.cc | 1 +
|
||||
content/public/common/content_features.cc | 1 +
|
||||
content/public/common/content_features.h | 1 +
|
||||
cromite_flags/BUILD.gn | 72 ++++++++++++++++
|
||||
.../browser/about_flags_cc/placeholder.txt | 1 +
|
||||
.../chrome_feature_list_cc/placeholder.txt | 1 +
|
||||
.../browser/ui/ui_features_cc/placeholder.txt | 1 +
|
||||
.../common/chrome_features_cc/placeholder.txt | 1 +
|
||||
.../common/chrome_features_h/placeholder.txt | 1 +
|
||||
.../common/features_cc/placeholder.txt | 1 +
|
||||
.../content_features_cc/placeholder.txt | 1 +
|
||||
.../common/content_features_h/placeholder.txt | 1 +
|
||||
.../blink/common/features_cc/placeholder.txt | 1 +
|
||||
third_party/blink/common/features.cc | 1 +
|
||||
31 files changed, 370 insertions(+), 10 deletions(-)
|
||||
create mode 100755 cromite_flags/BUILD.gn
|
||||
create mode 100755 cromite_flags/chrome/browser/about_flags_cc/placeholder.txt
|
||||
create mode 100755 cromite_flags/chrome/browser/flags/android/chrome_feature_list_cc/placeholder.txt
|
||||
create mode 100755 cromite_flags/chrome/browser/ui/ui_features_cc/placeholder.txt
|
||||
create mode 100755 cromite_flags/chrome/common/chrome_features_cc/placeholder.txt
|
||||
create mode 100755 cromite_flags/chrome/common/chrome_features_h/placeholder.txt
|
||||
create mode 100755 cromite_flags/content/common/features_cc/placeholder.txt
|
||||
create mode 100755 cromite_flags/content/public/common/content_features_cc/placeholder.txt
|
||||
create mode 100755 cromite_flags/content/public/common/content_features_h/placeholder.txt
|
||||
create mode 100755 cromite_flags/third_party/blink/common/features_cc/placeholder.txt
|
||||
|
||||
diff --git a/base/BUILD.gn b/base/BUILD.gn
|
||||
--- a/base/BUILD.gn
|
||||
+++ b/base/BUILD.gn
|
||||
@@ -206,6 +206,8 @@ buildflag_header("message_pump_buildflags") {
|
||||
# This does not include test code (test support and anything in the test
|
||||
# directory) which should use source_set as is recommended for GN targets).
|
||||
component("base") {
|
||||
+ deps = [ "//cromite_flags", ]
|
||||
+
|
||||
sources = [
|
||||
"allocator/allocator_check.cc",
|
||||
"allocator/allocator_check.h",
|
||||
@@ -1034,7 +1036,7 @@ component("base") {
|
||||
"//build/config/compiler:wglobal_constructors",
|
||||
]
|
||||
|
||||
- deps = [
|
||||
+ deps += [
|
||||
":message_pump_buildflags",
|
||||
"//base/allocator:buildflags",
|
||||
"//base/allocator/partition_allocator:raw_ptr",
|
||||
diff --git a/base/feature_list.cc b/base/feature_list.cc
|
||||
--- a/base/feature_list.cc
|
||||
+++ b/base/feature_list.cc
|
||||
@@ -29,6 +29,33 @@
|
||||
#include "base/strings/stringprintf.h"
|
||||
#include "build/build_config.h"
|
||||
|
||||
+namespace base {
|
||||
+namespace internal {
|
||||
+
|
||||
+using DefaultStateOverrides =
|
||||
+ flat_map<const Feature*, FeatureState>;
|
||||
+
|
||||
+constexpr size_t kDefaultStateOverridesReserve = 64 * 4;
|
||||
+
|
||||
+DefaultStateOverrides& GetListOfNewFeatureState() {
|
||||
+ static NoDestructor<DefaultStateOverrides>
|
||||
+ startup_default_state_overrides([] {
|
||||
+ DefaultStateOverrides v;
|
||||
+ v.reserve(kDefaultStateOverridesReserve);
|
||||
+ return v;
|
||||
+ }());
|
||||
+ return *startup_default_state_overrides;
|
||||
+}
|
||||
+
|
||||
+FeatureDefaultStateOverrider::FeatureDefaultStateOverrider(
|
||||
+ const Feature& feature, FeatureState state) {
|
||||
+ auto& default_state_overrides = GetListOfNewFeatureState();
|
||||
+ default_state_overrides.insert({&feature, state});
|
||||
+}
|
||||
+
|
||||
+} // namespace internal
|
||||
+} // namespace base
|
||||
+
|
||||
namespace base {
|
||||
|
||||
namespace {
|
||||
@@ -436,6 +463,24 @@ bool FeatureList::IsEnabled(const Feature& feature) {
|
||||
return g_feature_list_instance->IsFeatureEnabled(feature);
|
||||
}
|
||||
|
||||
+bool FeatureList::IsCromiteChanged(const Feature& feature) {
|
||||
+ for(auto const& [key, value]: internal::GetListOfNewFeatureState()) {
|
||||
+ if (key->name == feature.name) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
+bool FeatureList::GetCromiteChange(const Feature& feature) {
|
||||
+ for(auto const& [key, value]: internal::GetListOfNewFeatureState()) {
|
||||
+ if (key->name == feature.name) {
|
||||
+ return value == base::FEATURE_ENABLED_BY_DEFAULT;
|
||||
+ }
|
||||
+ }
|
||||
+ NOTREACHED();
|
||||
+ return false;
|
||||
+}
|
||||
// static
|
||||
bool FeatureList::IsValidFeatureOrFieldTrialName(StringPiece name) {
|
||||
return IsStringASCII(name) && name.find_first_of(",<*") == std::string::npos;
|
||||
@@ -616,6 +661,17 @@ void FeatureList::SetCachingContextForTesting(uint16_t caching_context) {
|
||||
|
||||
void FeatureList::FinalizeInitialization() {
|
||||
DCHECK(!initialized_);
|
||||
+ LOG(INFO) << "---FinalizeInitialization";
|
||||
+ for(auto const& [key, value]: internal::GetListOfNewFeatureState()) {
|
||||
+ LOG(INFO) << "---key " << key->name
|
||||
+ << " "
|
||||
+ << (value == base::FEATURE_ENABLED_BY_DEFAULT ? "1" : "0");
|
||||
+ RegisterOverride(key->name,
|
||||
+ value == base::FEATURE_ENABLED_BY_DEFAULT
|
||||
+ ? OverrideState::OVERRIDE_ENABLE_FEATURE
|
||||
+ : OverrideState::OVERRIDE_DISABLE_FEATURE,
|
||||
+ /* field_trial = */ nullptr);
|
||||
+ }
|
||||
// Store the field trial list pointer for DCHECKing.
|
||||
field_trial_list_ = FieldTrialList::GetInstance();
|
||||
initialized_ = true;
|
||||
diff --git a/base/feature_list.h b/base/feature_list.h
|
||||
--- a/base/feature_list.h
|
||||
+++ b/base/feature_list.h
|
||||
@@ -93,8 +93,10 @@ enum FeatureState {
|
||||
// [1]:
|
||||
// https://crsrc.org/c/docs/speed/binary_size/android_binary_size_trybot.md#Mutable-Constants
|
||||
struct BASE_EXPORT LOGICALLY_CONST Feature {
|
||||
- constexpr Feature(const char* name, FeatureState default_state)
|
||||
- : name(name), default_state(default_state) {
|
||||
+ constexpr Feature(const char* name, FeatureState default_state,
|
||||
+ bool cromite = false, bool is_new_flag = false)
|
||||
+ : name(name), default_state(default_state),
|
||||
+ is_cromite(cromite), is_new(is_new_flag) {
|
||||
#if BUILDFLAG(ENABLE_BANNED_BASE_FEATURE_PREFIX)
|
||||
if (StringPiece(name).find(BUILDFLAG(BANNED_BASE_FEATURE_PREFIX)) == 0) {
|
||||
LOG(FATAL) << "Invalid feature name " << name << " starts with "
|
||||
@@ -120,6 +122,9 @@ struct BASE_EXPORT LOGICALLY_CONST Feature {
|
||||
// command line switch.
|
||||
const FeatureState default_state;
|
||||
|
||||
+ const bool is_cromite = false;
|
||||
+ const bool is_new = false;
|
||||
+
|
||||
private:
|
||||
friend class FeatureList;
|
||||
|
||||
@@ -395,6 +400,9 @@ class BASE_EXPORT FeatureList {
|
||||
// instance, which is checked in builds with DCHECKs enabled.
|
||||
static bool IsEnabled(const Feature& feature);
|
||||
|
||||
+ static bool IsCromiteChanged(const Feature& feature);
|
||||
+ static bool GetCromiteChange(const Feature& feature);
|
||||
+
|
||||
// Some characters are not allowed to appear in feature names or the
|
||||
// associated field trial names, as they are used as special characters for
|
||||
// command-line serialization. This function checks that the strings are ASCII
|
||||
@@ -616,4 +624,76 @@ class BASE_EXPORT FeatureList {
|
||||
|
||||
} // namespace base
|
||||
|
||||
+namespace base {
|
||||
+namespace internal {
|
||||
+
|
||||
+// Perform base::Feature duplicates check and fills overriden states into a
|
||||
+// map that is used at runtime to get an override if available.
|
||||
+class BASE_EXPORT FeatureDefaultStateOverrider {
|
||||
+ public:
|
||||
+ using FeatureOverrideInfo =
|
||||
+ std::pair<std::reference_wrapper<const Feature>, FeatureState>;
|
||||
+
|
||||
+ FeatureDefaultStateOverrider(
|
||||
+ const Feature& feature, FeatureState state);
|
||||
+};
|
||||
+
|
||||
+} // namespace internal
|
||||
+} // namespace base
|
||||
+
|
||||
+#define CROMITE_FEATURE(feature, name, default_state) \
|
||||
+ CONSTINIT const base::Feature feature(name, default_state, true, true)
|
||||
+
|
||||
+#define CROMITE_FEATURE_KEEP_DISABLED(feature, name, default_state) \
|
||||
+ CONSTINIT const base::Feature feature(name, base::FEATURE_DISABLED_BY_DEFAULT, true); \
|
||||
+ static_assert(default_state == base::FEATURE_DISABLED_BY_DEFAULT, \
|
||||
+ "Feature is not disabled by default.")
|
||||
+
|
||||
+#define CROMITE_FEATURE_DISABLED(feature, name, default_state) \
|
||||
+ CONSTINIT const base::Feature feature(name, base::FEATURE_DISABLED_BY_DEFAULT, true); \
|
||||
+ static_assert(default_state == base::FEATURE_ENABLED_BY_DEFAULT, \
|
||||
+ "Feature is not enabled by default.")
|
||||
+
|
||||
+#define CROMITE_FEATURE_KEEP_ENABLED(feature, name, default_state) \
|
||||
+ CONSTINIT const base::Feature feature(name, base::FEATURE_ENABLED_BY_DEFAULT, true); \
|
||||
+ static_assert(default_state == base::FEATURE_ENABLED_BY_DEFAULT, \
|
||||
+ "Feature is not enabled by default.")
|
||||
+
|
||||
+#define CROMITE_FEATURE_ENABLED(feature, name, default_state) \
|
||||
+ CONSTINIT const base::Feature feature(name, base::FEATURE_ENABLED_BY_DEFAULT, true); \
|
||||
+ static_assert(default_state == base::FEATURE_DISABLED_BY_DEFAULT, \
|
||||
+ "Feature is not disabled by default.")
|
||||
+
|
||||
+#define SET_CROMITE_FEATURE_ENABLED(feature) \
|
||||
+ _Pragma("clang diagnostic push") \
|
||||
+ _Pragma("clang diagnostic ignored \"-Wglobal-constructors\"") \
|
||||
+ static const ::base::internal::FeatureDefaultStateOverrider \
|
||||
+ g_feature_default_state_overrider_ ##feature {feature, base::FEATURE_ENABLED_BY_DEFAULT}; \
|
||||
+ _Pragma("clang diagnostic pop") \
|
||||
+ static_assert(true, "") /* for a semicolon requirement */
|
||||
+
|
||||
+#define SET_CROMITE_FEATURE_DISABLED(feature) \
|
||||
+ _Pragma("clang diagnostic push") \
|
||||
+ _Pragma("clang diagnostic ignored \"-Wglobal-constructors\"") \
|
||||
+ static const ::base::internal::FeatureDefaultStateOverrider \
|
||||
+ g_feature_default_state_overrider_ ##feature {feature, base::FEATURE_DISABLED_BY_DEFAULT}; \
|
||||
+ _Pragma("clang diagnostic pop") \
|
||||
+ static_assert(true, "") /* for a semicolon requirement */
|
||||
+
|
||||
+#define SET_CROMITE_FEATURE_ENABLED_W_NAMESPACE(namespace_value, feature) \
|
||||
+ _Pragma("clang diagnostic push") \
|
||||
+ _Pragma("clang diagnostic ignored \"-Wglobal-constructors\"") \
|
||||
+ static const ::base::internal::FeatureDefaultStateOverrider \
|
||||
+ g_feature_default_state_overrider_ ##feature {namespace_value::feature, base::FEATURE_ENABLED_BY_DEFAULT}; \
|
||||
+ _Pragma("clang diagnostic pop") \
|
||||
+ static_assert(true, "") /* for a semicolon requirement */
|
||||
+
|
||||
+#define SET_CROMITE_FEATURE_DISABLED_W_NAMESPACE(namespace_value, feature) \
|
||||
+ _Pragma("clang diagnostic push") \
|
||||
+ _Pragma("clang diagnostic ignored \"-Wglobal-constructors\"") \
|
||||
+ static const ::base::internal::FeatureDefaultStateOverrider \
|
||||
+ g_feature_default_state_overrider_ ##feature {namespace_value::feature, base::FEATURE_DISABLED_BY_DEFAULT}; \
|
||||
+ _Pragma("clang diagnostic pop") \
|
||||
+ static_assert(true, "") /* for a semicolon requirement */
|
||||
+
|
||||
#endif // BASE_FEATURE_LIST_H_
|
||||
diff --git a/build/android/gyp/java_cpp_features.py b/build/android/gyp/java_cpp_features.py
|
||||
--- a/build/android/gyp/java_cpp_features.py
|
||||
+++ b/build/android/gyp/java_cpp_features.py
|
||||
@@ -22,10 +22,27 @@ class FeatureParserDelegate(java_cpp_utils.CppConstantParser.Delegate):
|
||||
# ExtractConstantName() -> 'ConstantName'
|
||||
# ExtractValue() -> '"StringNameOfTheFeature"'
|
||||
FEATURE_RE = re.compile(r'BASE_FEATURE\(k([^,]+),')
|
||||
+
|
||||
+ FEATURE_RE1 = re.compile(r'CROMITE_FEATURE\(k([^,]+),')
|
||||
+ FEATURE_RE2 = re.compile(r'CROMITE_FEATURE_KEEP_DISABLED\(k([^,]+),')
|
||||
+ FEATURE_RE3 = re.compile(r'CROMITE_FEATURE_DISABLED\(k([^,]+),')
|
||||
+ FEATURE_RE4 = re.compile(r'CROMITE_FEATURE_KEEP_ENABLED\(k([^,]+),')
|
||||
+ FEATURE_RE5 = re.compile(r'CROMITE_FEATURE_ENABLED\(k([^,]+),')
|
||||
+
|
||||
VALUE_RE = re.compile(r'\s*("(?:\"|[^"])*")\s*,')
|
||||
|
||||
def ExtractConstantName(self, line):
|
||||
match = FeatureParserDelegate.FEATURE_RE.match(line)
|
||||
+ if match is None:
|
||||
+ match = FeatureParserDelegate.FEATURE_RE1.match(line)
|
||||
+ if match is None:
|
||||
+ match = FeatureParserDelegate.FEATURE_RE2.match(line)
|
||||
+ if match is None:
|
||||
+ match = FeatureParserDelegate.FEATURE_RE3.match(line)
|
||||
+ if match is None:
|
||||
+ match = FeatureParserDelegate.FEATURE_RE4.match(line)
|
||||
+ if match is None:
|
||||
+ match = FeatureParserDelegate.FEATURE_RE5.match(line)
|
||||
return match.group(1) if match else None
|
||||
|
||||
def ExtractValue(self, line):
|
||||
diff --git a/chrome/android/java/res/values/values.xml b/chrome/android/java/res/values/values.xml
|
||||
--- a/chrome/android/java/res/values/values.xml
|
||||
+++ b/chrome/android/java/res/values/values.xml
|
||||
@@ -42,6 +42,9 @@ found in the LICENSE file.
|
||||
<!-- Contextual Search -->
|
||||
<item name="contextual_search_sheet_full_height_fraction" format="float" type="dimen">0.95</item>
|
||||
|
||||
+ <string name="cromite_flags_title">Cromite Flags (wip)</string>
|
||||
+ <string name="cromite_flags_url">chrome://flags/cromite</string>
|
||||
+
|
||||
<!-- Tablet tab strip -->
|
||||
<item name="compositor_background_tab_outline_alpha" format="float" type="dimen">0.5</item>
|
||||
<item name="compositor_background_tab_overlay_alpha" format="float" type="dimen">0</item>
|
||||
diff --git a/chrome/android/java/res/xml/privacy_preferences.xml b/chrome/android/java/res/xml/privacy_preferences.xml
|
||||
--- a/chrome/android/java/res/xml/privacy_preferences.xml
|
||||
+++ b/chrome/android/java/res/xml/privacy_preferences.xml
|
||||
@@ -99,6 +99,10 @@ found in the LICENSE file.
|
||||
android:title="@string/tabgrid_use_icons_title"
|
||||
android:summary="@string/tabgrid_use_icons_summary"
|
||||
android:defaultValue="false" />
|
||||
+ <org.chromium.chrome.browser.about_settings.HyperlinkPreference
|
||||
+ android:key="cromite_flags"
|
||||
+ android:title="@string/cromite_flags_title"
|
||||
+ app:url="@string/cromite_flags_url" />
|
||||
<Preference
|
||||
android:key="privacy_sandbox"
|
||||
android:title="@string/prefs_privacy_sandbox"
|
||||
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
|
||||
--- a/chrome/browser/about_flags.cc
|
||||
+++ b/chrome/browser/about_flags.cc
|
||||
@@ -4096,6 +4096,10 @@ const FeatureEntry::FeatureVariation kWebAuthnAndroidCredManVariations[] = {
|
||||
nullptr}};
|
||||
#endif // BUILDFLAG(IS_ANDROID)
|
||||
|
||||
+#define FEATURE_PARAM_SECTION
|
||||
+#include "cromite_flags/chrome_browser_about_flags_cc.inc"
|
||||
+#undef FEATURE_PARAM_SECTION
|
||||
+
|
||||
// RECORDING USER METRICS FOR FLAGS:
|
||||
// -----------------------------------------------------------------------------
|
||||
// The first line of the entry is the internal name.
|
||||
@@ -4122,6 +4126,9 @@ const FeatureEntry::FeatureVariation kWebAuthnAndroidCredManVariations[] = {
|
||||
const FeatureEntry kFeatureEntries[] = {
|
||||
// Include generated flags for flag unexpiry; see //docs/flag_expiry.md and
|
||||
// //tools/flags/generate_unexpire_flags.py.
|
||||
+#define FLAG_SECTION
|
||||
+#include "cromite_flags/chrome_browser_about_flags_cc.inc"
|
||||
+#undef FLAG_SECTION
|
||||
#include "build/chromeos_buildflags.h"
|
||||
#include "chrome/browser/unexpire_flags_gen.inc"
|
||||
{variations::switches::kEnableBenchmarking,
|
||||
diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc
|
||||
--- a/chrome/browser/flags/android/chrome_feature_list.cc
|
||||
+++ b/chrome/browser/flags/android/chrome_feature_list.cc
|
||||
@@ -1244,5 +1244,6 @@ BASE_FEATURE(kBookmarksExportUseSaf,
|
||||
"BookmarksExportUseSaf",
|
||||
base::FEATURE_DISABLED_BY_DEFAULT);
|
||||
|
||||
+#include "cromite_flags/chrome_browser_flags_android_chrome_feature_list_cc.inc"
|
||||
} // namespace android
|
||||
} // namespace chrome
|
||||
diff --git a/chrome/browser/ui/ui_features.cc b/chrome/browser/ui/ui_features.cc
|
||||
--- a/chrome/browser/ui/ui_features.cc
|
||||
+++ b/chrome/browser/ui/ui_features.cc
|
||||
@@ -394,4 +394,5 @@ BASE_FEATURE(kStopLoadingAnimationForHiddenWindow,
|
||||
"StopLoadingAnimationForHiddenWindow",
|
||||
base::FEATURE_ENABLED_BY_DEFAULT);
|
||||
|
||||
+#include "cromite_flags/chrome_browser_ui_ui_features_cc.inc"
|
||||
} // namespace features
|
||||
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc
|
||||
--- a/chrome/common/chrome_features.cc
|
||||
+++ b/chrome/common/chrome_features.cc
|
||||
@@ -1649,4 +1649,5 @@ BASE_FEATURE(kSupportsRtcWakeOver24Hours,
|
||||
base::FEATURE_ENABLED_BY_DEFAULT);
|
||||
#endif // BUILDFLAG(IS_CHROMEOS_ASH)
|
||||
|
||||
+#include "cromite_flags/chrome_common_chrome_features_cc.inc"
|
||||
} // namespace features
|
||||
diff --git a/components/flags_ui/flags_state.cc b/components/flags_ui/flags_state.cc
|
||||
--- a/components/flags_ui/flags_state.cc
|
||||
+++ b/components/flags_ui/flags_state.cc
|
||||
@@ -668,6 +668,27 @@ void FlagsState::GetFlagFeatureEntries(
|
||||
bool is_default_value = IsDefaultValue(entry, enabled_entries);
|
||||
data.Set("is_default", is_default_value);
|
||||
|
||||
+ if (entry.type == FeatureEntry::FEATURE_VALUE
|
||||
+ || entry.type == FeatureEntry::FEATURE_WITH_PARAMS_VALUE) {
|
||||
+ DCHECK(entry.feature.feature);
|
||||
+ if (base::FeatureList::IsCromiteChanged(*entry.feature.feature)) {
|
||||
+ bool is_enabled = base::FeatureList::GetCromiteChange(*entry.feature.feature);
|
||||
+ data.Set("is_cromite", true);
|
||||
+ data.Set("default_value",
|
||||
+ is_enabled ? "enabled" : "disabled");
|
||||
+ } else {
|
||||
+ bool is_enabled = entry.feature.feature->default_state == base::FEATURE_ENABLED_BY_DEFAULT;
|
||||
+ data.Set("default_value", is_enabled
|
||||
+ ? "enabled" : "disabled");
|
||||
+ if (is_enabled)
|
||||
+ data.Set("is_default_value_on", true);
|
||||
+ }
|
||||
+ if (entry.feature.feature->is_cromite)
|
||||
+ data.Set("is_cromite", true);
|
||||
+ if (entry.feature.feature->is_new)
|
||||
+ data.Set("is_new", true);
|
||||
+ }
|
||||
+
|
||||
switch (entry.type) {
|
||||
case FeatureEntry::SINGLE_VALUE:
|
||||
case FeatureEntry::SINGLE_DISABLE_VALUE:
|
||||
diff --git a/components/flags_ui/resources/experiment.html b/components/flags_ui/resources/experiment.html
|
||||
--- a/components/flags_ui/resources/experiment.html
|
||||
+++ b/components/flags_ui/resources/experiment.html
|
||||
@@ -119,6 +119,11 @@
|
||||
color: white;
|
||||
}
|
||||
|
||||
+ .experiment-on select {
|
||||
+ background: #dddddd;
|
||||
+ color: var(--link-color);
|
||||
+ }
|
||||
+
|
||||
.experiment-switched option {
|
||||
background: white;
|
||||
color: var(--link-color);
|
||||
@@ -164,7 +169,6 @@
|
||||
.experiment .experiment-actions {
|
||||
max-width: 100%;
|
||||
padding-top: 12px;
|
||||
- text-align: left; /* csschecker-disable-line left-right */
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@@ -172,7 +176,6 @@
|
||||
.body {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
- white-space: nowrap;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
diff --git a/components/flags_ui/resources/experiment.ts b/components/flags_ui/resources/experiment.ts
|
||||
--- a/components/flags_ui/resources/experiment.ts
|
||||
+++ b/components/flags_ui/resources/experiment.ts
|
||||
@@ -60,11 +60,16 @@ function resetHighlights(element: HTMLElement) {
|
||||
|
||||
export class FlagsExperimentElement extends CustomElement {
|
||||
private feature_: Feature|null = null;
|
||||
+ private permalink_: boolean = true;
|
||||
|
||||
static override get template() {
|
||||
return getTemplate();
|
||||
}
|
||||
|
||||
+ set permalink(visible: boolean) {
|
||||
+ this.permalink_ = visible;
|
||||
+ }
|
||||
+
|
||||
set data(feature: Feature) {
|
||||
this.feature_ = feature;
|
||||
|
||||
@@ -76,12 +81,18 @@ export class FlagsExperimentElement extends CustomElement {
|
||||
'experiment-default', feature.is_default);
|
||||
experimentDefault.classList.toggle(
|
||||
'experiment-switched', !feature.is_default);
|
||||
+ experimentDefault.classList.toggle(
|
||||
+ 'cromite', feature.is_cromite && feature.is_new);
|
||||
+ experimentDefault.classList.toggle(
|
||||
+ 'experiment-on', !!feature.is_default_value_on);
|
||||
|
||||
const experimentName = this.getRequiredElement('.experiment-name');
|
||||
experimentName.id = `${feature.internal_name}_name`;
|
||||
experimentName.title =
|
||||
feature.is_default ? '' : loadTimeData.getString('experiment-enabled');
|
||||
experimentName.textContent = feature.name;
|
||||
+ if (feature.is_cromite && feature.is_new)
|
||||
+ experimentName.textContent += " (Cromite flag)"
|
||||
|
||||
const description = this.getRequiredElement('.description');
|
||||
description.textContent = feature.description;
|
||||
@@ -124,6 +135,7 @@ export class FlagsExperimentElement extends CustomElement {
|
||||
const permalink = this.getRequiredElement<HTMLAnchorElement>('.permalink');
|
||||
permalink.href = `#${feature.internal_name}`;
|
||||
permalink.textContent = `#${feature.internal_name}`;
|
||||
+ if (!this.permalink_) permalink.hidden = true;
|
||||
|
||||
const smallScreenCheck = window.matchMedia('(max-width: 480px)');
|
||||
// Toggling of experiment description overflow content on smaller screens.
|
||||
@@ -152,6 +164,10 @@ export class FlagsExperimentElement extends CustomElement {
|
||||
const optionEl = document.createElement('option');
|
||||
optionEl.selected = option.selected;
|
||||
optionEl.textContent = option.description;
|
||||
+ if (option.description == "Default" &&
|
||||
+ feature.default_value !== undefined) {
|
||||
+ optionEl.textContent += " (" + feature.default_value + ")";
|
||||
+ }
|
||||
experimentSelect.appendChild(optionEl);
|
||||
}
|
||||
|
||||
diff --git a/components/flags_ui/resources/flags.css b/components/flags_ui/resources/flags.css
|
||||
--- a/components/flags_ui/resources/flags.css
|
||||
+++ b/components/flags_ui/resources/flags.css
|
||||
@@ -468,3 +468,22 @@ button.primary:-webkit-any(:active, :hover) {
|
||||
padding-top: 1.5rem;
|
||||
}
|
||||
}
|
||||
+
|
||||
+.cromite #header {
|
||||
+ display: none;
|
||||
+}
|
||||
+.cromite .blurb-container {
|
||||
+ display: none;
|
||||
+}
|
||||
+.cromite #tabs {
|
||||
+ display: none;
|
||||
+}
|
||||
+.cromite #tab-content-available {
|
||||
+ display: none;
|
||||
+}
|
||||
+.cromite #tab-content-unavailable {
|
||||
+ display: none;
|
||||
+}
|
||||
+.cromite #tab-content-cromite {
|
||||
+ display: block !important;
|
||||
+}
|
||||
diff --git a/components/flags_ui/resources/flags.html b/components/flags_ui/resources/flags.html
|
||||
--- a/components/flags_ui/resources/flags.html
|
||||
+++ b/components/flags_ui/resources/flags.html
|
||||
@@ -92,6 +92,11 @@
|
||||
aria-selected="false" aria-controls="panel2"
|
||||
tabindex="-1">$i18n{unavailable}</a>
|
||||
</if>
|
||||
+ <a href="#tab-content-cromite" id="tab-cromite" class="tab"
|
||||
+ role="tab"
|
||||
+ aria-selected="true"
|
||||
+ aria-controls="panel1"
|
||||
+ tabindex="5">Cromite</a>
|
||||
</div>
|
||||
<div id="tabpanels">
|
||||
<div id="tab-content-available" class="tab-content selected"
|
||||
@@ -111,6 +116,14 @@
|
||||
</div>
|
||||
</div>
|
||||
</if>
|
||||
+ <div id="tab-content-cromite" class="tab-content"
|
||||
+ role="tabpanel" aria-labelledby="tab-cromite" aria-hidden="false">
|
||||
+ <!-- Non default experiments. -->
|
||||
+ <div id="non-default-cromite-experiments"></div>
|
||||
+ <!-- Experiments with default settings. -->
|
||||
+ <div id="cromite-experiments"></div>
|
||||
+ <div class="no-match hidden" role="alert">$i18n{no-results}</div>
|
||||
+ </div>
|
||||
</div>
|
||||
<div id="needs-restart" jsvalues="class:needsRestart ? 'show' : ''">
|
||||
<div class="flex-container">
|
||||
diff --git a/components/flags_ui/resources/flags.ts b/components/flags_ui/resources/flags.ts
|
||||
--- a/components/flags_ui/resources/flags.ts
|
||||
+++ b/components/flags_ui/resources/flags.ts
|
||||
@@ -39,6 +39,10 @@ interface Tab {
|
||||
}
|
||||
|
||||
const tabs: Tab[] = [
|
||||
+ {
|
||||
+ tabEl: document.body.querySelector('#tab-cromite')!,
|
||||
+ panelEl: document.body.querySelector('#tab-content-cromite')!,
|
||||
+ },
|
||||
{
|
||||
tabEl: document.body.querySelector('#tab-available')!,
|
||||
panelEl: document.body.querySelector('#tab-content-available')!,
|
||||
@@ -84,18 +88,27 @@ function render(experimentalFeaturesData: ExperimentalFeaturesData) {
|
||||
const defaultFeatures: Feature[] = [];
|
||||
const nonDefaultFeatures: Feature[] = [];
|
||||
|
||||
+ if (document.body.classList.contains("cromite")) {
|
||||
+ experimentalFeaturesData.supportedFeatures =
|
||||
+ experimentalFeaturesData.supportedFeatures.filter(item => item.is_new);
|
||||
+ }
|
||||
+ experimentalFeaturesData.supportedFeatures.sort(
|
||||
+ (a,b) => (a.internal_name.localeCompare(b.internal_name)));
|
||||
experimentalFeaturesData.supportedFeatures.forEach(
|
||||
f => (f.is_default ? defaultFeatures : nonDefaultFeatures).push(f));
|
||||
|
||||
renderExperiments(
|
||||
- nonDefaultFeatures, getRequiredElement('non-default-experiments'));
|
||||
+ nonDefaultFeatures, getRequiredElement('non-default-experiments'),
|
||||
+ getRequiredElement('non-default-cromite-experiments'), false);
|
||||
|
||||
- renderExperiments(defaultFeatures, getRequiredElement('default-experiments'));
|
||||
+ renderExperiments(defaultFeatures, getRequiredElement('default-experiments'),
|
||||
+ getRequiredElement('cromite-experiments'), false);
|
||||
|
||||
// <if expr="not is_ios">
|
||||
renderExperiments(
|
||||
experimentalFeaturesData.unsupportedFeatures,
|
||||
- getRequiredElement('unavailable-experiments'), true);
|
||||
+ getRequiredElement('unavailable-experiments'),
|
||||
+ undefined, true);
|
||||
// </if>
|
||||
|
||||
showRestartToast(experimentalFeaturesData.needsRestart);
|
||||
@@ -248,16 +261,22 @@ function resetAllFlags() {
|
||||
}
|
||||
|
||||
function renderExperiments(
|
||||
- features: Feature[], container: HTMLElement, unsupported = false) {
|
||||
+ features: Feature[], container: HTMLElement, cromiteContainer: HTMLElement | undefined, unsupported: boolean) {
|
||||
const fragment = document.createDocumentFragment();
|
||||
+ const fragmentCromite = document.createDocumentFragment();
|
||||
+ const show_permalink = !document.body.classList.contains('cromite');
|
||||
for (const feature of features) {
|
||||
const experiment = document.createElement('flags-experiment');
|
||||
|
||||
experiment.toggleAttribute('unsupported', unsupported);
|
||||
+ experiment.permalink = show_permalink;
|
||||
experiment.data = feature;
|
||||
experiment.id = feature.internal_name;
|
||||
|
||||
const select = experiment.getSelect();
|
||||
+ // if (select && feature.is_cromite && !feature.is_new) {
|
||||
+ // select.disabled = true;
|
||||
+ // }
|
||||
if (select) {
|
||||
experiment.addEventListener('select-change', () => {
|
||||
showRestartToast(true);
|
||||
@@ -281,9 +300,14 @@ function renderExperiments(
|
||||
return false;
|
||||
});
|
||||
}
|
||||
- fragment.appendChild(experiment);
|
||||
+ if (feature.is_cromite)
|
||||
+ fragmentCromite.appendChild(experiment);
|
||||
+ else
|
||||
+ fragment.appendChild(experiment);
|
||||
}
|
||||
container.replaceChildren(fragment);
|
||||
+ if (!!cromiteContainer)
|
||||
+ cromiteContainer.replaceChildren(fragmentCromite);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -507,6 +531,8 @@ function setupRestartButton() {
|
||||
// </if>
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
+ if (location.pathname == '/cromite')
|
||||
+ document.body.classList.add('cromite');
|
||||
// Get and display the data upon loading.
|
||||
requestExperimentalFeaturesData();
|
||||
// There is no restart button on iOS.
|
||||
diff --git a/components/flags_ui/resources/flags_browser_proxy.ts b/components/flags_ui/resources/flags_browser_proxy.ts
|
||||
--- a/components/flags_ui/resources/flags_browser_proxy.ts
|
||||
+++ b/components/flags_ui/resources/flags_browser_proxy.ts
|
||||
@@ -16,6 +16,11 @@ export interface Feature {
|
||||
description: string;
|
||||
enabled: boolean;
|
||||
is_default: boolean;
|
||||
+ is_default_value_on: boolean;
|
||||
+ default_value: string;
|
||||
+ is_cromite: boolean;
|
||||
+ is_new: boolean;
|
||||
+ permalink: boolean;
|
||||
supported_platforms: string[];
|
||||
origin_list_value?: string;
|
||||
string_value?: string;
|
||||
diff --git a/content/common/features.cc b/content/common/features.cc
|
||||
--- a/content/common/features.cc
|
||||
+++ b/content/common/features.cc
|
||||
@@ -529,4 +529,5 @@ BASE_FEATURE(kWindowOpenFileSelectFix,
|
||||
|
||||
// Please keep features in alphabetical order.
|
||||
|
||||
+#include "cromite_flags/content_common_features_cc.inc"
|
||||
} // namespace features
|
||||
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc
|
||||
--- a/content/public/common/content_features.cc
|
||||
+++ b/content/public/common/content_features.cc
|
||||
@@ -1331,4 +1331,5 @@ bool IsVideoCaptureServiceEnabledForBrowserProcess() {
|
||||
VideoCaptureServiceConfiguration::kEnabledForBrowserProcess;
|
||||
}
|
||||
|
||||
+#include "cromite_flags/content_public_common_content_features_cc.inc"
|
||||
} // namespace features
|
||||
diff --git a/content/public/common/content_features.h b/content/public/common/content_features.h
|
||||
--- a/content/public/common/content_features.h
|
||||
+++ b/content/public/common/content_features.h
|
||||
@@ -330,6 +330,7 @@ CONTENT_EXPORT BASE_DECLARE_FEATURE(kWebRtcPipeWireCapturer);
|
||||
CONTENT_EXPORT bool IsVideoCaptureServiceEnabledForOutOfProcess();
|
||||
CONTENT_EXPORT bool IsVideoCaptureServiceEnabledForBrowserProcess();
|
||||
|
||||
+#include "cromite_flags/content_public_common_content_features_h.inc"
|
||||
} // namespace features
|
||||
|
||||
#endif // CONTENT_PUBLIC_COMMON_CONTENT_FEATURES_H_
|
||||
diff --git a/cromite_flags/BUILD.gn b/cromite_flags/BUILD.gn
|
||||
new file mode 100755
|
||||
--- /dev/null
|
||||
+++ b/cromite_flags/BUILD.gn
|
||||
@@ -0,0 +1,72 @@
|
||||
+# This file is part of Bromite.
|
||||
+
|
||||
+# Bromite is free software: you can redistribute it and/or modify
|
||||
+# it under the terms of the GNU General Public License as published by
|
||||
+# the Free Software Foundation, either version 3 of the License, or
|
||||
+# (at your option) any later version.
|
||||
+
|
||||
+# Bromite is distributed in the hope that it will be useful,
|
||||
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+# GNU General Public License for more details.
|
||||
+
|
||||
+# You should have received a copy of the GNU General Public License
|
||||
+# along with Bromite. If not, see <https://www.gnu.org/licenses/>.
|
||||
+
|
||||
+# for placeholder.txt:
|
||||
+#
|
||||
+# this file is intentionally empty
|
||||
+#
|
||||
+
|
||||
+cpp_bromite_include("chrome_browser_about_flags_cc") {
|
||||
+ inputs = [ "//cromite_flags/chrome/browser/about_flags_cc/placeholder.txt" ]
|
||||
+ output_file = "chrome_browser_about_flags_cc.inc"
|
||||
+}
|
||||
+
|
||||
+cpp_bromite_include("chrome_common_chrome_features_cc") {
|
||||
+ inputs = [ "//cromite_flags/chrome/common/chrome_features_cc/placeholder.txt" ]
|
||||
+ output_file = "chrome_common_chrome_features_cc.inc"
|
||||
+}
|
||||
+
|
||||
+cpp_bromite_include("content_common_features_cc") {
|
||||
+ inputs = [ "//cromite_flags/content/common/features_cc/placeholder.txt" ]
|
||||
+ output_file = "content_common_features_cc.inc"
|
||||
+}
|
||||
+
|
||||
+cpp_bromite_include("content_public_common_content_features_h") {
|
||||
+ inputs = [ "//cromite_flags/content/public/common/content_features_h/placeholder.txt" ]
|
||||
+ output_file = "content_public_common_content_features_h.inc"
|
||||
+}
|
||||
+
|
||||
+cpp_bromite_include("content_public_common_content_features_cc") {
|
||||
+ inputs = [ "//cromite_flags/content/public/common/content_features_cc/placeholder.txt" ]
|
||||
+ output_file = "content_public_common_content_features_cc.inc"
|
||||
+}
|
||||
+
|
||||
+cpp_bromite_include("third_party_blink_common_features_cc") {
|
||||
+ inputs = [ "//cromite_flags/third_party/blink/common/features_cc/placeholder.txt" ]
|
||||
+ output_file = "third_party_blink_common_features_cc.inc"
|
||||
+}
|
||||
+
|
||||
+cpp_bromite_include("chrome_browser_flags_android_chrome_feature_list_cc") {
|
||||
+ inputs = [ "//cromite_flags/chrome/browser/flags/android/chrome_feature_list_cc/placeholder.txt" ]
|
||||
+ output_file = "chrome_browser_flags_android_chrome_feature_list_cc.inc"
|
||||
+}
|
||||
+
|
||||
+cpp_bromite_include("chrome_browser_ui_ui_features_cc") {
|
||||
+ inputs = [ "//cromite_flags/chrome/browser/ui/ui_features_cc/placeholder.txt" ]
|
||||
+ output_file = "chrome_browser_ui_ui_features_cc.inc"
|
||||
+}
|
||||
+
|
||||
+component("cromite_flags") {
|
||||
+ deps = [
|
||||
+ ":content_common_features_cc",
|
||||
+ ":content_public_common_content_features_cc",
|
||||
+ ":content_public_common_content_features_h",
|
||||
+ ":chrome_common_chrome_features_cc",
|
||||
+ ":chrome_browser_about_flags_cc",
|
||||
+ ":chrome_browser_flags_android_chrome_feature_list_cc",
|
||||
+ ":chrome_browser_ui_ui_features_cc",
|
||||
+ ":third_party_blink_common_features_cc",
|
||||
+ ]
|
||||
+}
|
||||
diff --git a/cromite_flags/chrome/browser/about_flags_cc/placeholder.txt b/cromite_flags/chrome/browser/about_flags_cc/placeholder.txt
|
||||
new file mode 100755
|
||||
--- /dev/null
|
||||
+++ b/cromite_flags/chrome/browser/about_flags_cc/placeholder.txt
|
||||
@@ -0,0 +1 @@
|
||||
+this file is intentionally empty
|
||||
diff --git a/cromite_flags/chrome/browser/flags/android/chrome_feature_list_cc/placeholder.txt b/cromite_flags/chrome/browser/flags/android/chrome_feature_list_cc/placeholder.txt
|
||||
new file mode 100755
|
||||
--- /dev/null
|
||||
+++ b/cromite_flags/chrome/browser/flags/android/chrome_feature_list_cc/placeholder.txt
|
||||
@@ -0,0 +1 @@
|
||||
+this file is intentionally empty
|
||||
diff --git a/cromite_flags/chrome/browser/ui/ui_features_cc/placeholder.txt b/cromite_flags/chrome/browser/ui/ui_features_cc/placeholder.txt
|
||||
new file mode 100755
|
||||
--- /dev/null
|
||||
+++ b/cromite_flags/chrome/browser/ui/ui_features_cc/placeholder.txt
|
||||
@@ -0,0 +1 @@
|
||||
+this file is intentionally empty
|
||||
diff --git a/cromite_flags/chrome/common/chrome_features_cc/placeholder.txt b/cromite_flags/chrome/common/chrome_features_cc/placeholder.txt
|
||||
new file mode 100755
|
||||
--- /dev/null
|
||||
+++ b/cromite_flags/chrome/common/chrome_features_cc/placeholder.txt
|
||||
@@ -0,0 +1 @@
|
||||
+this file is intentionally empty
|
||||
diff --git a/cromite_flags/chrome/common/chrome_features_h/placeholder.txt b/cromite_flags/chrome/common/chrome_features_h/placeholder.txt
|
||||
new file mode 100755
|
||||
--- /dev/null
|
||||
+++ b/cromite_flags/chrome/common/chrome_features_h/placeholder.txt
|
||||
@@ -0,0 +1 @@
|
||||
+this file is intentionally empty
|
||||
diff --git a/cromite_flags/content/common/features_cc/placeholder.txt b/cromite_flags/content/common/features_cc/placeholder.txt
|
||||
new file mode 100755
|
||||
--- /dev/null
|
||||
+++ b/cromite_flags/content/common/features_cc/placeholder.txt
|
||||
@@ -0,0 +1 @@
|
||||
+this file is intentionally empty
|
||||
diff --git a/cromite_flags/content/public/common/content_features_cc/placeholder.txt b/cromite_flags/content/public/common/content_features_cc/placeholder.txt
|
||||
new file mode 100755
|
||||
--- /dev/null
|
||||
+++ b/cromite_flags/content/public/common/content_features_cc/placeholder.txt
|
||||
@@ -0,0 +1 @@
|
||||
+this file is intentionally empty
|
||||
diff --git a/cromite_flags/content/public/common/content_features_h/placeholder.txt b/cromite_flags/content/public/common/content_features_h/placeholder.txt
|
||||
new file mode 100755
|
||||
--- /dev/null
|
||||
+++ b/cromite_flags/content/public/common/content_features_h/placeholder.txt
|
||||
@@ -0,0 +1 @@
|
||||
+this file is intentionally empty
|
||||
diff --git a/cromite_flags/third_party/blink/common/features_cc/placeholder.txt b/cromite_flags/third_party/blink/common/features_cc/placeholder.txt
|
||||
new file mode 100755
|
||||
--- /dev/null
|
||||
+++ b/cromite_flags/third_party/blink/common/features_cc/placeholder.txt
|
||||
@@ -0,0 +1 @@
|
||||
+this file is intentionally empty
|
||||
diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc
|
||||
--- a/third_party/blink/common/features.cc
|
||||
+++ b/third_party/blink/common/features.cc
|
||||
@@ -2192,5 +2192,6 @@ bool IsKeepAliveURLLoaderServiceEnabled() {
|
||||
base::FeatureList::IsEnabled(kFetchLaterAPI);
|
||||
}
|
||||
|
||||
+#include "cromite_flags/third_party_blink_common_features_cc.inc"
|
||||
} // namespace features
|
||||
} // namespace blink
|
||||
--
|
||||
2.25.1
|
||||
Reference in New Issue
Block a user