blob: 3fd43342731c2ab09111ad73d002ec1b6d90c463 [file] [log] [blame]
// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "ios/chrome/browser/shared/public/features/features.h"
#import <string>
#import <vector>
#import "base/containers/contains.h"
#import "base/metrics/field_trial_params.h"
#import "components/country_codes/country_codes.h"
#import "components/segmentation_platform/public/features.h"
#import "components/sync/base/features.h"
#import "components/version_info/channel.h"
#import "ios/chrome/app/background_mode_buildflags.h"
#import "ios/chrome/browser/ntp/shared/metrics/feed_metrics_constants.h"
#import "ios/chrome/browser/safety_check_notifications/utils/constants.h"
#import "ios/chrome/common/channel_info.h"
#import "ui/base/device_form_factor.h"
BASE_FEATURE(IOSKeyboardAccessoryUpgradeForIPad,
base::FEATURE_ENABLED_BY_DEFAULT);
BASE_FEATURE(TestFeature, base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(SafetyCheckMagicStack, base::FEATURE_ENABLED_BY_DEFAULT);
BASE_FEATURE(SafetyCheckAutorunByManagerKillswitch,
base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(SafetyCheckModuleHiddenIfNoIssuesKillswitch,
base::FEATURE_ENABLED_BY_DEFAULT);
BASE_FEATURE(SafetyCheckNotifications, base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(OmahaServiceRefactor, base::FEATURE_DISABLED_BY_DEFAULT);
const char kTipsLensShopExperimentType[] = "TipsLensShopExperimentType";
const char kTipsSafeBrowsingExperimentType[] = "TipsSafeBrowsingExperimentType";
const char kSafetyCheckNotificationsExperimentType[] =
"SafetyCheckNotificationsExperimentType";
const char kSafetyCheckNotificationsImpressionTrigger[] =
"SafetyCheckNotificationsImpressionTrigger";
const char kSafetyCheckNotificationsImpressionLimit[] =
"SafetyCheckNotificationsImpressionLimit";
const char kSafetyCheckAllowPasswordsNotifications[] =
"SafetyCheckAllowPasswordsNotifications";
const char kSafetyCheckAllowSafeBrowsingNotifications[] =
"SafetyCheckAllowSafeBrowsingNotifications";
const char kSafetyCheckAllowUpdateChromeNotifications[] =
"SafetyCheckAllowUpdateChromeNotifications";
const char kSafetyCheckMagicStackAutorunHoursThreshold[] =
"SafetyCheckMagicStackAutorunHoursThreshold";
const char kSafetyCheckNotificationsProvisionalEnabled[] =
"SafetyCheckNotificationsProvisionalEnabled";
const char kSafetyCheckNotificationsSuppressDelayIfPresent[] =
"SafetyCheckNotificationsSuppressDelayIfPresent";
const char kSafetyCheckNotificationsUserInactiveThreshold[] =
"SafetyCheckNotificationsUserInactiveThreshold";
// This helper should return true by default, as this parameter primarily serves
// as a killswitch.
bool AreSafetyCheckPasswordsNotificationsAllowed() {
return base::GetFieldTrialParamByFeatureAsBool(
kSafetyCheckNotifications, kSafetyCheckAllowPasswordsNotifications,
/*default_value=*/true);
}
// This helper should return true by default, as this parameter primarily serves
// as a killswitch.
bool AreSafetyCheckSafeBrowsingNotificationsAllowed() {
return base::GetFieldTrialParamByFeatureAsBool(
kSafetyCheckNotifications, kSafetyCheckAllowSafeBrowsingNotifications,
/*default_value=*/true);
}
// This helper should return true by default, as this parameter primarily serves
// as a killswitch.
bool AreSafetyCheckUpdateChromeNotificationsAllowed() {
return base::GetFieldTrialParamByFeatureAsBool(
kSafetyCheckNotifications, kSafetyCheckAllowUpdateChromeNotifications,
/*default_value=*/true);
}
bool ProvisionalSafetyCheckNotificationsEnabled() {
return base::GetFieldTrialParamByFeatureAsBool(
kSafetyCheckNotifications, kSafetyCheckNotificationsProvisionalEnabled,
/*default_value=*/
true);
}
const base::TimeDelta SuppressDelayForSafetyCheckNotificationsIfPresent() {
return base::GetFieldTrialParamByFeatureAsTimeDelta(
kSafetyCheckNotifications,
kSafetyCheckNotificationsSuppressDelayIfPresent,
/*default_value=*/kSafetyCheckNotificationSuppressDelayIfPresent);
}
const base::TimeDelta InactiveThresholdForSafetyCheckNotifications() {
return base::GetFieldTrialParamByFeatureAsTimeDelta(
kSafetyCheckNotifications, kSafetyCheckNotificationsUserInactiveThreshold,
/*default_value=*/
kSafetyCheckNotificationDefaultDelay);
}
// How many hours between each autorun of the Safety Check in the Magic Stack.
const base::TimeDelta TimeDelayForSafetyCheckAutorun() {
int delay = base::GetFieldTrialParamByFeatureAsInt(
kSafetyCheckMagicStack, kSafetyCheckMagicStackAutorunHoursThreshold,
/*default_value=*/720);
return base::Hours(delay);
}
BASE_FEATURE(SharedHighlightingIOS, base::FEATURE_ENABLED_BY_DEFAULT);
BASE_FEATURE(ShareInWebContextMenuIOS, base::FEATURE_ENABLED_BY_DEFAULT);
BASE_FEATURE(IOSBrowserEditMenuMetrics, base::FEATURE_DISABLED_BY_DEFAULT);
const char kIOSDockingPromoExperimentType[] = "IOSDockingPromoExperimentType";
const char kIOSDockingPromoNewUserInactiveThresholdHours[] =
"IOSDockingPromoNewUserInactiveThresholdHours";
const char kIOSDockingPromoOldUserInactiveThresholdHours[] =
"IOSDockingPromoOldUserInactiveThresholdHours";
const char kIOSDockingPromoNewUserInactiveThreshold[] =
"IOSDockingPromoNewUserInactiveThreshold";
const char kIOSDockingPromoOldUserInactiveThreshold[] =
"IOSDockingPromoOldUserInactiveThreshold";
BASE_FEATURE(IOSDockingPromo, base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(IOSDockingPromoForEligibleUsersOnly,
base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(IOSDockingPromoFixedTriggerLogicKillswitch,
base::FEATURE_ENABLED_BY_DEFAULT);
BASE_FEATURE(IOSDockingPromoPreventDeregistrationKillswitch,
base::FEATURE_ENABLED_BY_DEFAULT);
BASE_FEATURE(EnableLensInOmniboxCopiedImage, base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(EnableLensOverlay, base::FEATURE_ENABLED_BY_DEFAULT);
BASE_FEATURE(EnableLensViewFinderUnifiedExperience,
base::FEATURE_DISABLED_BY_DEFAULT);
// Update to the correct milestone after launch.
// Also update in components/omnibox/browser/autocomplete_result.cc.
const base::NotFatalUntil kLensOverlayNotFatalUntil = base::NotFatalUntil::M200;
BASE_FEATURE(LensLoadAIMInLensResultPage, base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(LensOverlayDisablePriceInsights,
base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(LensOverlayPriceInsightsCounterfactual,
base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(kLensOverlayEnableIPadCompatibility,
"EnableLensOverlayForceIPadSupport",
base::FEATURE_ENABLED_BY_DEFAULT);
BASE_FEATURE(kLensOverlayEnableLandscapeCompatibility,
"EnableLensOverlayLandscapeSupport",
base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(LensOverlayEnableLVFEscapeHatch, base::FEATURE_ENABLED_BY_DEFAULT);
BASE_FEATURE(LensOverlayEnableLocationBarEntrypoint,
base::FEATURE_ENABLED_BY_DEFAULT);
BASE_FEATURE(LensOverlayEnableLocationBarEntrypointOnSRP,
base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(kLensOverlayEnableSameTabNavigation,
"EnableLensOverlaySameTabNavigation",
base::FEATURE_ENABLED_BY_DEFAULT);
BASE_FEATURE(kLensOverlayForceShowOnboardingScreen,
"EnableLensOverlayForceShowOnboardingScreen",
base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(LensOverlayNavigationHistory, base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(LensSearchHeadersCheckEnabled, base::FEATURE_DISABLED_BY_DEFAULT);
// Variations of MIA NTP entrypoint.
const char kNTPMIAEntrypointParam[] = "kNTPMIAEntrypointParam";
const char kNTPMIAEntrypointParamOmniboxContainedSingleButton[] =
"kNTPMIAEntrypointParamOmniboxContainedSingleButton";
const char kNTPMIAEntrypointParamOmniboxContainedInline[] =
"kNTPMIAEntrypointParamOmniboxContainedInline";
const char kNTPMIAEntrypointParamOmniboxContainedEnlargedFakebox[] =
"kNTPMIAEntrypointParamOmniboxContainedEnlargedFakebox";
const char kNTPMIAEntrypointParamEnlargedFakeboxNoIncognito[] =
"kNTPMIAEntrypointParamEnlargedFakeboxNoIncognito";
// Feature flag to change the MIA entrypoint in NTP.
BASE_FEATURE(kNTPMIAEntrypoint,
"kNTPMIAEntrypoint",
base::FEATURE_DISABLED_BY_DEFAULT);
// When enabled the AIM ZPS entrypoint will open the AIM prototype which
// contains temporary UI exploration for AIM.
BASE_FEATURE(AIMPrototype, base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(OmniboxDRSPrototype, base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(EnableTraitCollectionWorkAround, base::FEATURE_ENABLED_BY_DEFAULT);
BASE_FEATURE(RemoveExcessNTPs, base::FEATURE_ENABLED_BY_DEFAULT);
BASE_FEATURE(kTCRexKillSwitch,
"kTCRexKillSwitch",
base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(TabGridNewTransitions, base::FEATURE_DISABLED_BY_DEFAULT);
bool IsNewTabGridTransitionsEnabled() {
if (IsDiamondPrototypeEnabled()) {
return false;
}
return base::FeatureList::IsEnabled(kTabGridNewTransitions);
}
BASE_FEATURE(ContextualPanelForceShowEntrypoint,
base::FEATURE_DISABLED_BY_DEFAULT);
bool IsContextualPanelForceShowEntrypointEnabled() {
return base::FeatureList::IsEnabled(kContextualPanelForceShowEntrypoint);
}
BASE_FEATURE(ContextualPanel, base::FEATURE_ENABLED_BY_DEFAULT);
bool IsContextualPanelEnabled() {
return base::FeatureList::IsEnabled(kContextualPanel);
}
constexpr base::FeatureParam<int> kLargeContextualPanelEntrypointDelayInSeconds{
&kContextualPanel,
/*name=*/"large-entrypoint-delay-seconds", /*default_value=*/2};
int LargeContextualPanelEntrypointDelayInSeconds() {
return kLargeContextualPanelEntrypointDelayInSeconds.Get();
}
constexpr base::FeatureParam<int>
kLargeContextualPanelEntrypointDisplayedInSeconds{
&kContextualPanel,
/*name=*/"large-entrypoint-displayed-seconds", /*default_value=*/4};
int LargeContextualPanelEntrypointDisplayedInSeconds() {
return kLargeContextualPanelEntrypointDisplayedInSeconds.Get();
}
constexpr base::FeatureParam<bool> kContextualPanelEntrypointHighlightDuringIPH{
&kContextualPanel,
/*name=*/"entrypoint-highlight-iph", /*default_value=*/true};
bool ShouldHighlightContextualPanelEntrypointDuringIPH() {
return kContextualPanelEntrypointHighlightDuringIPH.Get();
}
constexpr base::FeatureParam<bool> kContextualPanelEntrypointRichIPH{
&kContextualPanel,
/*name=*/"entrypoint-rich-iph", /*default_value=*/true};
bool ShouldShowRichContextualPanelEntrypointIPH() {
return kContextualPanelEntrypointRichIPH.Get();
}
BASE_FEATURE(NonModalDefaultBrowserPromoImpressionLimit,
base::FEATURE_ENABLED_BY_DEFAULT);
constexpr base::FeatureParam<int>
kNonModalDefaultBrowserPromoImpressionLimitParam{
&kNonModalDefaultBrowserPromoImpressionLimit,
/*name=*/"impression-limit", /*default_value=*/3};
BASE_FEATURE(NotificationSettingsMenuItem, base::FEATURE_ENABLED_BY_DEFAULT);
const char kBottomOmniboxDefaultSettingParam[] =
"BottomOmniboxDefaultSettingParam";
const char kBottomOmniboxDefaultSettingParamTop[] = "Top";
const char kBottomOmniboxDefaultSettingParamBottom[] = "Bottom";
const char kBottomOmniboxDefaultSettingParamSafariSwitcher[] =
"BottomSafariSwitcher";
BASE_FEATURE(BottomOmniboxDefaultSetting, base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(BottomOmniboxEvolution, base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(OnlyAccessClipboardAsync, base::FEATURE_ENABLED_BY_DEFAULT);
BASE_FEATURE(ThemeColorInTopToolbar, base::FEATURE_DISABLED_BY_DEFAULT);
bool IsSafetyCheckAutorunByManagerEnabled() {
return base::FeatureList::IsEnabled(kSafetyCheckAutorunByManagerKillswitch);
}
bool IsSafetyCheckMagicStackEnabled() {
return base::FeatureList::IsEnabled(kSafetyCheckMagicStack);
}
bool ShouldHideSafetyCheckModuleIfNoIssues() {
return base::FeatureList::IsEnabled(
kSafetyCheckModuleHiddenIfNoIssuesKillswitch);
}
bool IsSafetyCheckNotificationsEnabled() {
return base::FeatureList::IsEnabled(kSafetyCheckNotifications);
}
bool IsOmahaServiceRefactorEnabled() {
return base::FeatureList::IsEnabled(kOmahaServiceRefactor);
}
SafetyCheckNotificationsExperimentalArm
SafetyCheckNotificationsExperimentTypeEnabled() {
return static_cast<SafetyCheckNotificationsExperimentalArm>(
base::GetFieldTrialParamByFeatureAsInt(
kSafetyCheckNotifications, kSafetyCheckNotificationsExperimentType,
/*default_value=*/
(int)SafetyCheckNotificationsExperimentalArm::kSuccinct));
}
SafetyCheckNotificationsImpressionTrigger
SafetyCheckNotificationsImpressionTriggerEnabled() {
return static_cast<SafetyCheckNotificationsImpressionTrigger>(
base::GetFieldTrialParamByFeatureAsInt(
kSafetyCheckNotifications, kSafetyCheckNotificationsImpressionTrigger,
/*default_value=*/
(int)SafetyCheckNotificationsImpressionTrigger::kAlways));
}
int SafetyCheckNotificationsImpressionLimit() {
return base::GetFieldTrialParamByFeatureAsInt(
kSafetyCheckNotifications, kSafetyCheckNotificationsImpressionLimit,
/*default_value=*/
3);
}
bool IsTipsMagicStackEnabled() {
return IsSegmentationTipsManagerEnabled();
}
TipsLensShopExperimentType TipsLensShopExperimentTypeEnabled() {
return static_cast<
TipsLensShopExperimentType>(base::GetFieldTrialParamByFeatureAsInt(
segmentation_platform::features::kSegmentationPlatformTipsEphemeralCard,
kTipsLensShopExperimentType,
/*default_value=*/
(int)TipsLensShopExperimentType::kWithProductImage));
}
TipsSafeBrowsingExperimentType TipsSafeBrowsingExperimentTypeEnabled() {
return static_cast<
TipsSafeBrowsingExperimentType>(base::GetFieldTrialParamByFeatureAsInt(
segmentation_platform::features::kSegmentationPlatformTipsEphemeralCard,
kTipsSafeBrowsingExperimentType,
/*default_value=*/
(int)TipsSafeBrowsingExperimentType::kShowEnhancedSafeBrowsingPromo));
}
BASE_FEATURE(IOSChooseFromDrive, base::FEATURE_ENABLED_BY_DEFAULT);
BASE_FEATURE(IOSChooseFromDriveSimulatedClick,
base::FEATURE_ENABLED_BY_DEFAULT);
BASE_FEATURE(IOSDownloadNoUIUpdateInBackground,
base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(IOSManageAccountStorage, base::FEATURE_ENABLED_BY_DEFAULT);
BASE_FEATURE(DeprecateFeedHeader, base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(EnableFeedBackgroundRefresh, base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(CreateDiscoverFeedServiceEarly, base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(EnableFeedAblation, base::FEATURE_DISABLED_BY_DEFAULT);
const char kContentPushNotificationsExperimentType[] =
"ContentPushNotificationsExperimentType";
BASE_FEATURE(ContentPushNotifications, base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(ContentNotificationExperiment, base::FEATURE_ENABLED_BY_DEFAULT);
bool IsContentNotificationExperimentEnabled() {
return base::FeatureList::IsEnabled(kContentNotificationExperiment);
}
BASE_FEATURE(ContentNotificationProvisionalIgnoreConditions,
base::FEATURE_DISABLED_BY_DEFAULT);
bool IsContentNotificationProvisionalIgnoreConditions() {
return base::FeatureList::IsEnabled(
kContentNotificationProvisionalIgnoreConditions);
}
BASE_FEATURE(ContentNotificationDeliveredNAU,
base::FEATURE_DISABLED_BY_DEFAULT);
const char kDeliveredNAUMaxPerSession[] = "DeliveredNAUMaxPerSession";
BASE_FEATURE(FullscreenImprovement, base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(NewSyncOptInIllustration, base::FEATURE_DISABLED_BY_DEFAULT);
bool IsNewSyncOptInIllustration() {
return base::FeatureList::IsEnabled(kNewSyncOptInIllustration);
}
BASE_FEATURE(DisableLensCamera, base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(DownloadAutoDeletionClearFilesOnEveryStartup,
base::FEATURE_DISABLED_BY_DEFAULT);
bool isDownloadAutoDeletionTestingFeatureEnabled() {
return base::FeatureList::IsEnabled(
kDownloadAutoDeletionClearFilesOnEveryStartup);
}
BASE_FEATURE(DownloadAutoDeletionFeatureEnabled,
base::FEATURE_DISABLED_BY_DEFAULT);
bool IsDownloadAutoDeletionFeatureEnabled() {
return base::FeatureList::IsEnabled(kDownloadAutoDeletionFeatureEnabled);
}
const char kDownloadListUITypeParam[] = "DownloadListUIType";
bool IsDownloadListEnabled() {
return base::FeatureList::IsEnabled(kDownloadList);
}
DownloadListUIType CurrentDownloadListUIType() {
CHECK(IsDownloadListEnabled());
return static_cast<DownloadListUIType>(base::GetFieldTrialParamByFeatureAsInt(
kDownloadList, kDownloadListUITypeParam, /*default_value=*/
(int)DownloadListUIType::kDefaultUI));
}
BASE_FEATURE(DownloadList, base::FEATURE_DISABLED_BY_DEFAULT);
// Key for NSUserDefaults containing a bool indicating whether the next run
// should enable feed background refresh capability. This is used because
// registering for background refreshes must happen early in app initialization
// and FeatureList is not yet available. Enabling or disabling background
// refresh features will always take effect after two cold starts after the
// feature has been changed on the server (once for the Finch configuration, and
// another for reading the stored value from NSUserDefaults).
NSString* const kEnableFeedBackgroundRefreshCapabilityForNextColdStart =
@"EnableFeedBackgroundRefreshCapabilityForNextColdStart";
const char kEnableFollowingFeedBackgroundRefresh[] =
"EnableFollowingFeedBackgroundRefresh";
const char kEnableServerDrivenBackgroundRefreshSchedule[] =
"EnableServerDrivenBackgroundRefreshSchedule";
const char kEnableRecurringBackgroundRefreshSchedule[] =
"EnableRecurringBackgroundRefreshSchedule";
const char kMaxCacheAgeInSeconds[] = "MaxCacheAgeInSeconds";
const char kBackgroundRefreshIntervalInSeconds[] =
"BackgroundRefreshIntervalInSeconds";
const char kBackgroundRefreshMaxAgeInSeconds[] =
"BackgroundRefreshMaxAgeInSeconds";
bool IsDockingPromoEnabled() {
return base::FeatureList::IsEnabled(kIOSDockingPromo);
}
bool IsDockingPromoForEligibleUsersOnlyEnabled() {
return base::FeatureList::IsEnabled(kIOSDockingPromoForEligibleUsersOnly);
}
DockingPromoDisplayTriggerArm DockingPromoExperimentTypeEnabled() {
return static_cast<DockingPromoDisplayTriggerArm>(
base::GetFieldTrialParamByFeatureAsInt(
kIOSDockingPromo, kIOSDockingPromoExperimentType,
/*default_value=*/(int)DockingPromoDisplayTriggerArm::kAfterFRE));
}
const base::TimeDelta InactiveThresholdForNewUsersUntilDockingPromoShown() {
return base::GetFieldTrialParamByFeatureAsTimeDelta(
kIOSDockingPromo, kIOSDockingPromoNewUserInactiveThreshold,
/*default_value=*/
base::Hours(HoursInactiveForNewUsersUntilShowingDockingPromo()));
}
const base::TimeDelta InactiveThresholdForOldUsersUntilDockingPromoShown() {
return base::GetFieldTrialParamByFeatureAsTimeDelta(
kIOSDockingPromo, kIOSDockingPromoOldUserInactiveThreshold,
/*default_value=*/
base::Hours(HoursInactiveForOldUsersUntilShowingDockingPromo()));
}
int HoursInactiveForNewUsersUntilShowingDockingPromo() {
return base::GetFieldTrialParamByFeatureAsInt(
kIOSDockingPromo, kIOSDockingPromoNewUserInactiveThresholdHours,
/*default_value=*/24);
}
int HoursInactiveForOldUsersUntilShowingDockingPromo() {
return base::GetFieldTrialParamByFeatureAsInt(
kIOSDockingPromo, kIOSDockingPromoOldUserInactiveThresholdHours,
/*default_value=*/72);
}
bool IsWebChannelsEnabled() {
return false;
}
bool IsDiscoverFeedServiceCreatedEarly() {
return base::FeatureList::IsEnabled(kCreateDiscoverFeedServiceEarly);
}
bool IsFeedBackgroundRefreshEnabled() {
return base::FeatureList::IsEnabled(kEnableFeedBackgroundRefresh);
}
void SetFeedRefreshTimestamp(NSDate* timestamp, NSString* NSUserDefaultsKey) {
NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.dateStyle = NSDateFormatterShortStyle;
dateFormatter.timeStyle = NSDateFormatterShortStyle;
dateFormatter.locale = [NSLocale autoupdatingCurrentLocale];
[[NSUserDefaults standardUserDefaults]
setObject:[dateFormatter stringFromDate:timestamp]
forKey:NSUserDefaultsKey];
}
bool IsFeedOverrideDefaultsEnabled() {
if (GetChannel() == version_info::Channel::STABLE) {
return false;
}
return [[NSUserDefaults standardUserDefaults]
boolForKey:@"FeedOverrideDefaultsEnabled"];
}
bool IsFollowingFeedBackgroundRefreshEnabled() {
if (IsFeedOverrideDefaultsEnabled()) {
return [[NSUserDefaults standardUserDefaults]
boolForKey:@"FollowingFeedBackgroundRefreshEnabled"];
}
return base::GetFieldTrialParamByFeatureAsBool(
kEnableFeedBackgroundRefresh, kEnableFollowingFeedBackgroundRefresh,
/*default=*/false);
}
bool IsServerDrivenBackgroundRefreshScheduleEnabled() {
if (IsFeedOverrideDefaultsEnabled()) {
return [[NSUserDefaults standardUserDefaults]
boolForKey:@"FeedServerDrivenBackgroundRefreshScheduleEnabled"];
}
return base::GetFieldTrialParamByFeatureAsBool(
kEnableFeedBackgroundRefresh,
kEnableServerDrivenBackgroundRefreshSchedule, /*default=*/false);
}
bool IsRecurringBackgroundRefreshScheduleEnabled() {
if (IsFeedOverrideDefaultsEnabled()) {
return [[NSUserDefaults standardUserDefaults]
boolForKey:@"FeedRecurringBackgroundRefreshScheduleEnabled"];
}
return base::GetFieldTrialParamByFeatureAsBool(
kEnableFeedBackgroundRefresh, kEnableRecurringBackgroundRefreshSchedule,
/*default=*/false);
}
double GetFeedMaxCacheAgeInSeconds() {
if (IsFeedOverrideDefaultsEnabled()) {
return [[NSUserDefaults standardUserDefaults]
doubleForKey:@"FeedMaxCacheAgeInSeconds"];
}
return base::GetFieldTrialParamByFeatureAsDouble(kEnableFeedBackgroundRefresh,
kMaxCacheAgeInSeconds,
/*default=*/8 * 60 * 60);
}
double GetBackgroundRefreshIntervalInSeconds() {
if (IsFeedOverrideDefaultsEnabled()) {
return [[NSUserDefaults standardUserDefaults]
doubleForKey:@"FeedBackgroundRefreshIntervalInSeconds"];
}
return base::GetFieldTrialParamByFeatureAsDouble(
kEnableFeedBackgroundRefresh, kBackgroundRefreshIntervalInSeconds,
/*default=*/60 * 60);
}
double GetBackgroundRefreshMaxAgeInSeconds() {
return base::GetFieldTrialParamByFeatureAsDouble(
kEnableFeedBackgroundRefresh, kBackgroundRefreshMaxAgeInSeconds,
/*default=*/0);
}
bool IsFeedAblationEnabled() {
return base::FeatureList::IsEnabled(kEnableFeedAblation);
}
bool IsFollowUIUpdateEnabled() {
return false;
}
bool IsContentPushNotificationsEnabled() {
return base::FeatureList::IsEnabled(kContentPushNotifications);
}
NotificationsExperimentType ContentNotificationsExperimentTypeEnabled() {
// This translates to the `NotificationsExperimentType` enum.
// Value 0 corresponds to `Enabled` on the feature flag. Only activates the
// Settings tab for content notifications.
return static_cast<NotificationsExperimentType>(
base::GetFieldTrialParamByFeatureAsInt(
kContentPushNotifications, kContentPushNotificationsExperimentType,
0));
}
bool IsContentPushNotificationsPromoEnabled() {
return (ContentNotificationsExperimentTypeEnabled() ==
NotificationsExperimentTypePromoEnabled);
}
bool IsContentPushNotificationsSetUpListEnabled() {
return (ContentNotificationsExperimentTypeEnabled() ==
NotificationsExperimentTypeSetUpListsEnabled);
}
bool IsContentPushNotificationsProvisionalEnabled() {
return (ContentNotificationsExperimentTypeEnabled() ==
NotificationsExperimentTypeProvisional);
}
bool IsContentPushNotificationsPromoRegistrationOnly() {
return (ContentNotificationsExperimentTypeEnabled() ==
NotificationsExperimentTypePromoRegistrationOnly);
}
bool IsContentPushNotificationsProvisionalRegistrationOnly() {
return (ContentNotificationsExperimentTypeEnabled() ==
NotificationsExperimentTypeProvisionalRegistrationOnly);
}
bool IsContentPushNotificationsSetUpListRegistrationOnly() {
return (ContentNotificationsExperimentTypeEnabled() ==
NotificationsExperimentTypeSetUpListsRegistrationOnly);
}
bool IsKeyboardAccessoryUpgradeEnabled() {
return (ui::GetDeviceFormFactor() != ui::DEVICE_FORM_FACTOR_TABLET) ||
base::FeatureList::IsEnabled(kIOSKeyboardAccessoryUpgradeForIPad);
}
bool IsLiquidGlassEffectEnabled() {
#if defined(__IPHONE_26_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_26_0
if (@available(iOS 26, *)) {
return IsKeyboardAccessoryUpgradeEnabled();
}
#endif // defined(__IPHONE_26_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >=
// __IPHONE_26_0
return false;
}
// Feature disabled by default.
BASE_FEATURE(MagicStack, base::FEATURE_ENABLED_BY_DEFAULT);
BASE_FEATURE(TabResumption, base::FEATURE_ENABLED_BY_DEFAULT);
// A parameter to indicate whether the native UI is enabled for the discover
// feed.
const char kDiscoverFeedIsNativeUIEnabled[] = "DiscoverFeedIsNativeUIEnabled";
const char kTabResumptionThresholdParameterName[] =
"tab-resumption-sync-threshold";
bool IsTabResumptionEnabled() {
return base::FeatureList::IsEnabled(kTabResumption);
}
const base::TimeDelta TabResumptionForXDevicesTimeThreshold() {
// Default to 12 hours.
int threshold = base::GetFieldTrialParamByFeatureAsInt(
kTabResumption, kTabResumptionThresholdParameterName,
/*default_value*/ 12 * 3600);
return base::Seconds(threshold);
}
BASE_FEATURE(TabResumptionImages, base::FEATURE_ENABLED_BY_DEFAULT);
const char kTabResumptionImagesTypes[] = "tr-images-type";
const char kTabResumptionImagesTypesSalient[] = "salient";
const char kTabResumptionImagesTypesThumbnails[] = "thumbnails";
bool IsTabResumptionImagesSalientEnabled() {
if (!base::FeatureList::IsEnabled(kTabResumptionImages)) {
return false;
}
std::string image_type = base::GetFieldTrialParamByFeatureAsString(
kTabResumptionImages, kTabResumptionImagesTypes, "");
return image_type == kTabResumptionImagesTypesSalient;
}
bool IsTabResumptionImagesThumbnailsEnabled() {
if (!base::FeatureList::IsEnabled(kTabResumptionImages)) {
return false;
}
std::string image_type = base::GetFieldTrialParamByFeatureAsString(
kTabResumptionImages, kTabResumptionImagesTypes, "");
return image_type == kTabResumptionImagesTypesThumbnails || image_type == "";
}
BASE_FEATURE(kInactiveNavigationAfterAppLaunchKillSwitch,
"kInactiveNavigationAfterAppLaunchKillSwitch",
base::FEATURE_DISABLED_BY_DEFAULT);
bool IsPinnedTabsEnabled() {
return ui::GetDeviceFormFactor() != ui::DEVICE_FORM_FACTOR_TABLET;
}
BASE_FEATURE(SegmentationPlatformIosModuleRankerCaching,
base::FEATURE_ENABLED_BY_DEFAULT);
bool IsSegmentationTipsManagerEnabled() {
return base::FeatureList::IsEnabled(
segmentation_platform::features::kSegmentationPlatformTipsEphemeralCard);
}
BASE_FEATURE(SpotlightNeverRetainIndex, base::FEATURE_DISABLED_BY_DEFAULT);
bool ShouldDeprecateFeedHeader() {
return base::FeatureList::IsEnabled(kDeprecateFeedHeader);
}
BASE_FEATURE(EnableAppBackgroundRefresh, base::FEATURE_DISABLED_BY_DEFAULT);
bool IsAppBackgroundRefreshEnabled() {
version_info::Channel channel = ::GetChannel();
if (channel == version_info::Channel::BETA ||
channel == version_info::Channel::STABLE) {
return false;
}
return base::FeatureList::IsEnabled(kEnableAppBackgroundRefresh);
}
BASE_FEATURE(HomeMemoryImprovements, base::FEATURE_DISABLED_BY_DEFAULT);
bool IsHomeMemoryImprovementsEnabled() {
return base::FeatureList::IsEnabled(kHomeMemoryImprovements);
}
BASE_FEATURE(IdentityConfirmationSnackbar, base::FEATURE_ENABLED_BY_DEFAULT);
// Feature parameters for kIdentityConfirmationSnackbar.
constexpr base::FeatureParam<base::TimeDelta>
kIdentityConfirmationMinDisplayInterval1{
&kIdentityConfirmationSnackbar,
/*name=*/"IdentityConfirmationMinDisplayInterval1",
/*default_value=*/base::Days(1)};
constexpr base::FeatureParam<base::TimeDelta>
kIdentityConfirmationMinDisplayInterval2{
&kIdentityConfirmationSnackbar,
/*name=*/"IdentityConfirmationMinDisplayInterval2",
/*default_value=*/base::Days(7)};
constexpr base::FeatureParam<base::TimeDelta>
kIdentityConfirmationMinDisplayInterval3{
&kIdentityConfirmationSnackbar,
/*name=*/"IdentityConfirmationMinDisplayInterval3",
/*default_value=*/base::Days(30)};
BASE_FEATURE(EnableTraitCollectionRegistration,
base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(BlueDotOnToolsMenuButton, base::FEATURE_ENABLED_BY_DEFAULT);
bool IsBlueDotOnToolsMenuButtoneEnabled() {
return base::FeatureList::IsEnabled(kBlueDotOnToolsMenuButton);
}
BASE_FEATURE(SeparateProfilesForManagedAccounts,
base::FEATURE_ENABLED_BY_DEFAULT);
// Feature parameter for kSeparateProfilesForManagedAccountsForceMigration.
constexpr base::FeatureParam<base::TimeDelta> kMultiProfileMigrationGracePeriod{
&kSeparateProfilesForManagedAccountsForceMigration,
/*name=*/"MultiProfileMigrationGracePeriod",
/*default_value=*/base::Days(90)};
BASE_FEATURE(SeparateProfilesForManagedAccountsForceMigration,
base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(SeparateProfilesForManagedAccountsKillSwitch,
base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(OmahaResyncTimerOnForeground, base::FEATURE_ENABLED_BY_DEFAULT);
BASE_FEATURE(ChromeStartupParametersAsync, base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(YoutubeIncognito, base::FEATURE_DISABLED_BY_DEFAULT);
const char kYoutubeIncognitoTargetApps[] = "youtube-incognito-target-apps";
const char kYoutubeIncognitoTargetAppsAllowlisted[] = "allow-listed";
const char kYoutubeIncognitoTargetAppsFirstParty[] = "first-party";
const char kYoutubeIncognitoTargetAppsAll[] = "all";
const char kYoutubeIncognitoErrorHandlingWithoutIncognitoInterstitialParam[] =
"youtube-incognito-error-handling-without-incognito-interstitial";
bool IsYoutubeIncognitoTargetAllowListedEnabled() {
std::string target_apps = base::GetFieldTrialParamByFeatureAsString(
kYoutubeIncognito, kYoutubeIncognitoTargetApps, "");
return target_apps == kYoutubeIncognitoTargetAppsAllowlisted ||
target_apps == "";
}
bool IsYoutubeIncognitoTargetFirstPartyEnabled() {
std::string target_apps = base::GetFieldTrialParamByFeatureAsString(
kYoutubeIncognito, kYoutubeIncognitoTargetApps, "");
return target_apps == kYoutubeIncognitoTargetAppsFirstParty;
}
bool IsYoutubeIncognitoTargetAllEnabled() {
std::string target_apps = base::GetFieldTrialParamByFeatureAsString(
kYoutubeIncognito, kYoutubeIncognitoTargetApps, "");
return target_apps == kYoutubeIncognitoTargetAppsAll;
}
bool IsYoutubeIncognitoErrorHandlingWithoutIncognitoInterstitialEnabled() {
return base::GetFieldTrialParamByFeatureAsBool(
kYoutubeIncognito,
kYoutubeIncognitoErrorHandlingWithoutIncognitoInterstitialParam, false);
}
BASE_FEATURE(IOSReactivationNotifications, base::FEATURE_DISABLED_BY_DEFAULT);
const char kIOSReactivationNotificationsTriggerTimeParam[] =
"reactivation_trigger_time";
const char kIOSReactivationNotificationsOrderParam[] = "reactivation_order";
bool IsIOSReactivationNotificationsEnabled() {
return base::FeatureList::IsEnabled(kIOSReactivationNotifications);
}
BASE_FEATURE(IOSExpandedTips, base::FEATURE_DISABLED_BY_DEFAULT);
const char kIOSExpandedTipsOrderParam[] = "expanded_tips_order";
bool IsIOSExpandedTipsEnabled() {
return base::FeatureList::IsEnabled(kIOSExpandedTips);
}
BASE_FEATURE(ProvisionalNotificationAlert, base::FEATURE_DISABLED_BY_DEFAULT);
bool IsProvisionalNotificationAlertEnabled() {
return base::FeatureList::IsEnabled(kProvisionalNotificationAlert);
}
BASE_FEATURE(IOSOneTimeDefaultBrowserNotification,
base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(DefaultBrowserBannerPromo, base::FEATURE_ENABLED_BY_DEFAULT);
constexpr base::FeatureParam<int> kDefaultBrowserBannerPromoImpressionLimit{
&kDefaultBrowserBannerPromo, "DefaultBrowserBannerPromoImpressionLimit", 5};
bool IsDefaultBrowserBannerPromoEnabled() {
return base::FeatureList::IsEnabled(kDefaultBrowserBannerPromo);
}
constexpr base::FeatureParam<std::string>
kFRESignInSecondaryActionLabelUpdateParam{
&kFRESignInSecondaryActionLabelUpdate,
"FRESignInSecondaryActionLabelUpdateParam", "StaySignedOut"};
const std::string_view kFRESignInSecondaryActionLabelUpdateParamStaySignedOut =
"StaySignedOut";
BASE_FEATURE(FRESignInSecondaryActionLabelUpdate,
base::FEATURE_ENABLED_BY_DEFAULT);
bool FRESignInSecondaryActionLabelUpdate() {
return base::FeatureList::IsEnabled(kFRESignInSecondaryActionLabelUpdate);
}
BASE_FEATURE(IOSPushNotificationMultiProfile, base::FEATURE_ENABLED_BY_DEFAULT);
const char kFullscreenTransitionSlower[] = "SlowFullscreenTransitionSpeed";
const char kFullscreenTransitionDefaultSpeed[] =
"MediumFullscreenTransitionSpeed";
const char kFullscreenTransitionFaster[] = "FastFullscreenTransitionSpeed";
const char kFullscreenTransitionSpeedParam[] = "FullscreenTransitionSpeed";
bool IsFullscreenTransitionSpeedSet() {
return base::FeatureList::IsEnabled(kFullscreenTransitionSpeed);
}
FullscreenTransitionSpeed FullscreenTransitionSpeedParam() {
return static_cast<FullscreenTransitionSpeed>(
base::GetFieldTrialParamByFeatureAsInt(
kFullscreenTransitionSpeed, kFullscreenTransitionSpeedParam, 1));
}
BASE_FEATURE(FullscreenTransitionSpeed, base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(RefactorToolbarsSize, base::FEATURE_DISABLED_BY_DEFAULT);
bool IsRefactorToolbarsSize() {
return base::FeatureList::IsEnabled(kRefactorToolbarsSize);
}
BASE_FEATURE(NewShareExtension, base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(IPHAblation, base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(LensOverlayDisableIPHPanGesture, base::FEATURE_ENABLED_BY_DEFAULT);
bool IsIPHAblationEnabled() {
return base::FeatureList::IsEnabled(kIPHAblation);
}
BASE_FEATURE(IPHGestureRecognitionAblation, base::FEATURE_ENABLED_BY_DEFAULT);
const char kIPHGestureRecognitionInsideTapAblation[] =
"IPHGestureRecognitionInsideTapAblation";
const char kIPHGestureRecognitionOutsideTapAblation[] =
"IPHGestureRecognitionOutsideTapAblation";
const char kIPHGestureRecognitionPanAblation[] =
"IPHGestureRecognitionPanAblation";
const char kIPHGestureRecognitionSwipeAblation[] =
"IPHGestureRecognitionSwipeAblation";
const char kCancelTouchesInViewForIPH[] = "CancelTouchesInViewForIPH";
const char kIPHGestureRecognitionImprovement[] =
"IPHGestureRecognitionImprovement";
bool IsIPHGestureRecognitionInsideTapAblationEnabled() {
return base::GetFieldTrialParamByFeatureAsBool(
kIPHGestureRecognitionAblation, kIPHGestureRecognitionInsideTapAblation,
false);
}
bool IsIPHGestureRecognitionOutsideTapAblationEnabled() {
return base::GetFieldTrialParamByFeatureAsBool(
kIPHGestureRecognitionAblation, kIPHGestureRecognitionOutsideTapAblation,
false);
}
bool IsIPHGestureRecognitionPanAblationEnabled() {
return base::GetFieldTrialParamByFeatureAsBool(
kIPHGestureRecognitionAblation, kIPHGestureRecognitionPanAblation, false);
}
bool IsIPHGestureRecognitionSwipeAblationEnabled() {
return base::GetFieldTrialParamByFeatureAsBool(
kIPHGestureRecognitionAblation, kIPHGestureRecognitionSwipeAblation,
false);
}
bool ShouldCancelTouchesInViewForIPH() {
return base::GetFieldTrialParamByFeatureAsBool(
kIPHGestureRecognitionAblation, kCancelTouchesInViewForIPH, false);
}
bool IsIPHGestureRecognitionImprovementEnabled() {
return base::GetFieldTrialParamByFeatureAsBool(
kIPHGestureRecognitionAblation, kIPHGestureRecognitionImprovement, false);
}
BASE_FEATURE(NonModalSignInPromo, base::FEATURE_DISABLED_BY_DEFAULT);
bool IsNonModalSignInPromoEnabled() {
return base::FeatureList::IsEnabled(kNonModalSignInPromo);
}
BASE_FEATURE(IOSOneTapMiniMapRestrictions, base::FEATURE_DISABLED_BY_DEFAULT);
const char kIOSOneTapMiniMapRestrictionCrossValidateParamName[] =
"ios-one-tap-minimap-cross-validate";
constexpr base::FeatureParam<bool>
kIOSOneTapMiniMapRestrictionCrossValidateParam{
&kIOSOneTapMiniMapRestrictions,
/*name=*/kIOSOneTapMiniMapRestrictionCrossValidateParamName,
/*default_value=*/false};
const char kIOSOneTapMiniMapRestrictionThreshholdParamName[] =
"ios-one-tap-minimap-threshhold";
constexpr base::FeatureParam<double>
kIOSOneTapMiniMapRestrictionThreshholdParam{
&kIOSOneTapMiniMapRestrictions,
/*name=*/kIOSOneTapMiniMapRestrictionThreshholdParamName,
/*default_value=*/0};
const char kIOSOneTapMiniMapRestrictionMinCharsParamName[] =
"ios-one-tap-minimap-min-chars";
constexpr base::FeatureParam<int> kIOSOneTapMiniMapRestrictionMinCharsParam{
&kIOSOneTapMiniMapRestrictions,
/*name=*/kIOSOneTapMiniMapRestrictionMinCharsParamName,
/*default_value=*/0};
const char kIOSOneTapMiniMapRestrictionMaxSectionsParamName[] =
"ios-one-tap-minimap-max-section";
constexpr base::FeatureParam<int> kIOSOneTapMiniMapRestrictionMaxSectionsParam{
&kIOSOneTapMiniMapRestrictions,
/*name=*/kIOSOneTapMiniMapRestrictionMaxSectionsParamName,
/*default_value=*/0};
const char kIOSOneTapMiniMapRestrictionLongestWordMinCharsParamName[] =
"ios-one-tap-minimap-longest-word-min-chars";
constexpr base::FeatureParam<int>
kIOSOneTapMiniMapRestrictionLongestWordMinCharsParam{
&kIOSOneTapMiniMapRestrictions,
/*name=*/kIOSOneTapMiniMapRestrictionLongestWordMinCharsParamName,
/*default_value=*/0};
const char kIOSOneTapMiniMapRestrictionMinAlphanumProportionParamName[] =
"ios-one-tap-minimap-min-alphanum-proportion";
constexpr base::FeatureParam<double>
kIOSOneTapMiniMapRestrictionMinAlphanumProportionParam{
&kIOSOneTapMiniMapRestrictions,
/*name=*/kIOSOneTapMiniMapRestrictionMinAlphanumProportionParamName,
/*default_value=*/0};
BASE_FEATURE(IOSOneTapMiniMapRemoveSectionsBreaks,
base::FEATURE_ENABLED_BY_DEFAULT);
BASE_FEATURE(IOSMiniMapUniversalLink, base::FEATURE_DISABLED_BY_DEFAULT);
bool IsNotificationCollisionManagementEnabled() {
return base::FeatureList::IsEnabled(kNotificationCollisionManagement);
}
BASE_FEATURE(NotificationCollisionManagement,
base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(IOSProvidesAppNotificationSettings,
base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(SignInButtonNoAvatar, base::FEATURE_ENABLED_BY_DEFAULT);
bool IsSignInButtonNoAvatarEnabled() {
return base::FeatureList::IsEnabled(kSignInButtonNoAvatar);
}
BASE_FEATURE(NTPBackgroundCustomization, base::FEATURE_DISABLED_BY_DEFAULT);
bool IsNTPBackgroundCustomizationEnabled() {
return base::FeatureList::IsEnabled(kNTPBackgroundCustomization);
}
BASE_FEATURE(RunDefaultStatusCheck, base::FEATURE_ENABLED_BY_DEFAULT);
bool IsRunDefaultStatusCheckEnabled() {
return base::FeatureList::IsEnabled(kRunDefaultStatusCheck);
}
BASE_FEATURE(BestOfAppFRE, base::FEATURE_DISABLED_BY_DEFAULT);
bool IsBestOfAppFREEnabled() {
return base::FeatureList::IsEnabled(kBestOfAppFRE);
}
bool IsBestOfAppGuidedTourEnabled() {
return base::GetFieldTrialParamValueByFeature(kBestOfAppFRE, "variant") ==
"4";
}
bool IsManualUploadForBestOfAppEnabled() {
return base::GetFieldTrialParamByFeatureAsBool(kBestOfAppFRE,
"manual_upload_uma", false);
}
bool IsBestOfAppLensInteractivePromoEnabled() {
return (ui::GetDeviceFormFactor() == ui::DEVICE_FORM_FACTOR_PHONE) &&
IsBestOfAppFREEnabled() &&
(base::GetFieldTrialParamValueByFeature(kBestOfAppFRE, "variant") ==
"1");
}
bool IsBestOfAppLensAnimatedPromoEnabled() {
return IsBestOfAppFREEnabled() && (base::GetFieldTrialParamValueByFeature(
kBestOfAppFRE, "variant") == "2");
}
BASE_FEATURE(FeedbackIncludeGWSVariations, base::FEATURE_ENABLED_BY_DEFAULT);
bool IsFeedbackIncludeGWSVariationsEnabled() {
return base::FeatureList::IsEnabled(kFeedbackIncludeGWSVariations);
}
bool IsDefaultBrowserPromoPropensityModelEnabled() {
return base::FeatureList::IsEnabled(
segmentation_platform::features::kDefaultBrowserPromoPropensityModel);
}
BASE_FEATURE(IOSTrustedVaultNotification, base::FEATURE_DISABLED_BY_DEFAULT);
bool IsIOSTrustedVaultNotificationEnabled() {
return base::FeatureList::IsEnabled(kIOSTrustedVaultNotification);
}
BASE_FEATURE(DiamondPrototype, base::FEATURE_DISABLED_BY_DEFAULT);
bool IsDiamondPrototypeEnabled() {
if (ui::GetDeviceFormFactor() != ui::DEVICE_FORM_FACTOR_PHONE) {
return false;
}
return base::FeatureList::IsEnabled(kDiamondPrototype);
}
BASE_FEATURE(IOSDefaultBrowserOffCyclePromo, base::FEATURE_DISABLED_BY_DEFAULT);
bool IsDefaultBrowserOffCyclePromoEnabled() {
#if defined(__IPHONE_18_3) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_18_3
if (@available(iOS 18.3, *)) {
return base::FeatureList::IsEnabled(kIOSDefaultBrowserOffCyclePromo);
}
#endif
return false;
}
BASE_FEATURE(IOSLogInstallAttribution, base::FEATURE_DISABLED_BY_DEFAULT);
bool IsInstallAttributionLoggingEnabled() {
return base::FeatureList::IsEnabled(kIOSLogInstallAttribution);
}
BASE_FEATURE(IOSUseDefaultAppsDestinationForPromos,
base::FEATURE_DISABLED_BY_DEFAULT);
bool IsDefaultAppsDestinationAvailable() {
#if defined(__IPHONE_18_3) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_18_3
if (@available(iOS 18.3, *)) {
return true;
}
#endif
return false;
}
bool IsUseDefaultAppsDestinationForPromosEnabled() {
return base::FeatureList::IsEnabled(kIOSUseDefaultAppsDestinationForPromos);
}
BASE_FEATURE(SynchronousEditMenuItems, base::FEATURE_ENABLED_BY_DEFAULT);
bool ShouldShowEditMenuItemsSynchronously() {
if (@available(iOS 26, *)) {
return base::FeatureList::IsEnabled(kSynchronousEditMenuItems);
}
return false;
}