blob: f7e76b26e6c36c656edc0e34268460e296f39eca [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/sync_preferences/features.h"
#import "components/version_info/channel.h"
#import "crypto/features.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(kTestFeature, base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(kSafetyCheckAutorunByManagerKillswitch,
base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(kSafetyCheckModuleHiddenIfNoIssuesKillswitch,
base::FEATURE_ENABLED_BY_DEFAULT);
BASE_FEATURE(kSafetyCheckNotifications, base::FEATURE_ENABLED_BY_DEFAULT);
BASE_FEATURE(kOmahaServiceRefactor, 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 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);
}
BASE_FEATURE(kHideToolbarsInOverflowMenu, base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(kSharedHighlightingIOS, base::FEATURE_ENABLED_BY_DEFAULT);
BASE_FEATURE(kShareInWebContextMenuIOS, base::FEATURE_ENABLED_BY_DEFAULT);
BASE_FEATURE(kIOSBrowserEditMenuMetrics, base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(kIOSCustomFileUploadMenu, 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(kIOSDockingPromo, base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(kIOSDockingPromoForEligibleUsersOnly,
base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(kIOSDockingPromoFixedTriggerLogicKillswitch,
base::FEATURE_ENABLED_BY_DEFAULT);
BASE_FEATURE(kIOSDockingPromoPreventDeregistrationKillswitch,
base::FEATURE_ENABLED_BY_DEFAULT);
BASE_FEATURE(kEnableLensInOmniboxCopiedImage,
base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(kEnableLensOverlay, base::FEATURE_ENABLED_BY_DEFAULT);
BASE_FEATURE(kEnableLensViewFinderUnifiedExperience,
base::FEATURE_ENABLED_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(kLensLoadAIMInLensResultPage, 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(kLensOverlayForceShowOnboardingScreen,
"EnableLensOverlayForceShowOnboardingScreen",
base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(kLensOverlayNavigationHistory, base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(kLensOverlayCustomBottomSheet, base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(kLensSearchHeadersCheckEnabled, base::FEATURE_ENABLED_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";
const char kNTPMIAEntrypointParamAIMInQuickActions[] =
"kNTPMIAEntrypointParamAIMInQuickActions";
// Feature flag to change the MIA entrypoint in NTP.
BASE_FEATURE(kNTPMIAEntrypoint,
"kNTPMIAEntrypoint",
base::FEATURE_ENABLED_BY_DEFAULT);
BASE_FEATURE(kNTPMIAEntrypointAllLocales,
"kNTPMIAEntrypointAllLocales",
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(kAIMPrototype, base::FEATURE_DISABLED_BY_DEFAULT);
const char kAIMPrototypeParam[] = "AIMPrototypeParam";
const char kAIMPrototypeParamAllOmniboxEntrypoints[] =
"AIMPrototypeAllOmniboxEntrypoints";
BASE_FEATURE(kAIMPrototypeAutoattachTab, base::FEATURE_DISABLED_BY_DEFAULT);
// Used to gate the immersive SRP in the AIM prototype.
BASE_FEATURE(kAIMPrototypeImmersiveSRP, base::FEATURE_DISABLED_BY_DEFAULT);
const char kAIMPrototypeTabPickerParam[] = "kAIMPrototypeTabPickerParam";
const char kAIMPrototypeTabPickerParamCachedAPC[] =
"kAIMPrototypeTabPickerParamCachedAPC";
const char kAIMPrototypeTabPickerParamOnFlightAPC[] =
"kAIMPrototypeTabPickerParamOnFlightAPC";
// Feature flag for the tab picker in the aim prototype.
BASE_FEATURE(kAIMPrototypeTabPicker, base::FEATURE_DISABLED_BY_DEFAULT);
bool IsAimPrototypeTabPickerCachedAPCEnabled() {
std::string param = base::GetFieldTrialParamValueByFeature(
kAIMPrototypeTabPicker, kAIMPrototypeTabPickerParam);
return param == kAIMPrototypeTabPickerParamCachedAPC;
}
BASE_FEATURE(kOmniboxDRSPrototype, base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(kEnableTraitCollectionWorkAround,
base::FEATURE_ENABLED_BY_DEFAULT);
BASE_FEATURE(kRemoveExcessNTPs, base::FEATURE_ENABLED_BY_DEFAULT);
BASE_FEATURE(kTCRexKillSwitch,
"kTCRexKillSwitch",
base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(kTabGridDragAndDrop, base::FEATURE_DISABLED_BY_DEFAULT);
bool IsTabGridDragAndDropEnabled() {
return base::FeatureList::IsEnabled(kTabGridDragAndDrop);
}
BASE_FEATURE(kTabGridEmptyThumbnail, base::FEATURE_DISABLED_BY_DEFAULT);
bool IsTabGridEmptyThumbnailUIEnabled() {
return base::FeatureList::IsEnabled(kTabGridEmptyThumbnail);
}
BASE_FEATURE(kTabGridNewTransitions, base::FEATURE_DISABLED_BY_DEFAULT);
bool IsNewTabGridTransitionsEnabled() {
if (IsDiamondPrototypeEnabled()) {
return false;
}
return base::FeatureList::IsEnabled(kTabGridNewTransitions);
}
BASE_FEATURE(kTabGroupInOverflowMenu, base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(kTabGroupInTabIconContextMenu, base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(kTabRecallNewTabGroupButton, base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(kTabSwitcherOverflowMenu, base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(kContextualPanelForceShowEntrypoint,
base::FEATURE_DISABLED_BY_DEFAULT);
bool IsContextualPanelForceShowEntrypointEnabled() {
return base::FeatureList::IsEnabled(kContextualPanelForceShowEntrypoint);
}
BASE_FEATURE(kContextualPanel, 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(kNonModalDefaultBrowserPromoImpressionLimit,
base::FEATURE_ENABLED_BY_DEFAULT);
constexpr base::FeatureParam<int>
kNonModalDefaultBrowserPromoImpressionLimitParam{
&kNonModalDefaultBrowserPromoImpressionLimit,
/*name=*/"impression-limit", /*default_value=*/3};
BASE_FEATURE(kNotificationSettingsMenuItem, base::FEATURE_ENABLED_BY_DEFAULT);
const char kBottomOmniboxEvolutionParam[] = "kBottomOmniboxEvolutionParam";
const char kBottomOmniboxEvolutionParamEditStateFollowSteadyState[] =
"kBottomOmniboxEvolutionParamEditStateFollowSteadyState";
const char kBottomOmniboxEvolutionParamForceBottomOmniboxEditState[] =
"kBottomOmniboxEvolutionParamForceBottomOmniboxEditState";
BASE_FEATURE(kBottomOmniboxEvolution, base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(kOnlyAccessClipboardAsync, base::FEATURE_ENABLED_BY_DEFAULT);
bool IsSafetyCheckAutorunByManagerEnabled() {
return base::FeatureList::IsEnabled(kSafetyCheckAutorunByManagerKillswitch);
}
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=*/
0);
}
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(kIOSChooseFromDrive, base::FEATURE_ENABLED_BY_DEFAULT);
BASE_FEATURE(kIOSDownloadNoUIUpdateInBackground,
base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(kIOSSaveToDriveClientFolder, base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(kIOSManageAccountStorage, base::FEATURE_ENABLED_BY_DEFAULT);
BASE_FEATURE(kEnableFeedBackgroundRefresh, base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(kEnableFeedAblation, base::FEATURE_DISABLED_BY_DEFAULT);
const char kContentPushNotificationsExperimentType[] =
"ContentPushNotificationsExperimentType";
BASE_FEATURE(kContentPushNotifications, base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(kContentNotificationProvisionalIgnoreConditions,
base::FEATURE_DISABLED_BY_DEFAULT);
bool IsContentNotificationProvisionalIgnoreConditions() {
return base::FeatureList::IsEnabled(
kContentNotificationProvisionalIgnoreConditions);
}
BASE_FEATURE(kContentNotificationDeliveredNAU,
base::FEATURE_DISABLED_BY_DEFAULT);
const char kDeliveredNAUMaxPerSession[] = "DeliveredNAUMaxPerSession";
BASE_FEATURE(kNewSyncOptInIllustration, base::FEATURE_DISABLED_BY_DEFAULT);
bool IsNewSyncOptInIllustration() {
return base::FeatureList::IsEnabled(kNewSyncOptInIllustration);
}
BASE_FEATURE(kDisableLensCamera, base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(kDownloadAutoDeletionClearFilesOnEveryStartup,
base::FEATURE_DISABLED_BY_DEFAULT);
bool isDownloadAutoDeletionTestingFeatureEnabled() {
return base::FeatureList::IsEnabled(
kDownloadAutoDeletionClearFilesOnEveryStartup);
}
BASE_FEATURE(kDownloadAutoDeletionFeatureEnabled,
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(kDownloadList, 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 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 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 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 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 IsLiquidGlassEffectEnabled() {
if (@available(iOS 26, *)) {
return true;
}
return false;
}
BASE_FEATURE(kIOSKeyboardAccessoryTwoBubble, base::FEATURE_DISABLED_BY_DEFAULT);
bool IsIOSKeyboardAccessoryTwoBubbleEnabled() {
return base::FeatureList::IsEnabled(kIOSKeyboardAccessoryTwoBubble);
}
BASE_FEATURE(kTabResumption, 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(kTabResumptionImages, 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(kSegmentationPlatformIosModuleRankerCaching,
base::FEATURE_ENABLED_BY_DEFAULT);
bool IsSegmentationTipsManagerEnabled() {
return base::FeatureList::IsEnabled(
segmentation_platform::features::kSegmentationPlatformTipsEphemeralCard);
}
BASE_FEATURE(kSpotlightNeverRetainIndex, base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(kEnableAppBackgroundRefresh, base::FEATURE_DISABLED_BY_DEFAULT);
bool IsAppBackgroundRefreshEnabled() {
// To test background refresh in conjunction with the keychain access
// migration, enable app background refresh if *either* its flag or
// the keychain access flag is enabled.
return base::FeatureList::IsEnabled(kEnableAppBackgroundRefresh) ||
base::FeatureList::IsEnabled(
crypto::features::kMigrateIOSKeychainAccessibility);
}
BASE_FEATURE(kHomeMemoryImprovements, base::FEATURE_DISABLED_BY_DEFAULT);
bool IsHomeMemoryImprovementsEnabled() {
return base::FeatureList::IsEnabled(kHomeMemoryImprovements);
}
BASE_FEATURE(kEnableTraitCollectionRegistration,
base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(kSeparateProfilesForManagedAccounts,
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(kSeparateProfilesForManagedAccountsForceMigration,
base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(kOmahaResyncTimerOnForeground, base::FEATURE_ENABLED_BY_DEFAULT);
BASE_FEATURE(kChromeStartupParametersAsync, base::FEATURE_ENABLED_BY_DEFAULT);
BASE_FEATURE(kYoutubeIncognito, base::FEATURE_ENABLED_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(kIOSReactivationNotifications, 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(kIOSExpandedTips, base::FEATURE_DISABLED_BY_DEFAULT);
const char kIOSExpandedTipsOrderParam[] = "expanded_tips_order";
bool IsIOSExpandedTipsEnabled() {
return base::FeatureList::IsEnabled(kIOSExpandedTips);
}
BASE_FEATURE(kProvisionalNotificationAlert, base::FEATURE_DISABLED_BY_DEFAULT);
bool IsProvisionalNotificationAlertEnabled() {
return base::FeatureList::IsEnabled(kProvisionalNotificationAlert);
}
BASE_FEATURE(kIOSOneTimeDefaultBrowserNotification,
base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(kDefaultBrowserBannerPromo, 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> kFRESignInHeaderTextUpdateParam{
&kFRESignInHeaderTextUpdate,
/*name=*/"FRESignInHeaderTextUpdateParam",
/*default_value=*/""};
const std::string_view kFRESignInHeaderTextUpdateParamArm0 = "Arm0";
const std::string_view kFRESignInHeaderTextUpdateParamArm1 = "Arm1";
BASE_FEATURE(kFRESignInHeaderTextUpdate, base::FEATURE_DISABLED_BY_DEFAULT);
bool FRESignInHeaderTextUpdate() {
return base::FeatureList::IsEnabled(kFRESignInHeaderTextUpdate);
}
constexpr base::FeatureParam<std::string>
kFRESignInSecondaryActionLabelUpdateParam{
&kFRESignInSecondaryActionLabelUpdate,
"FRESignInSecondaryActionLabelUpdateParam", "StaySignedOut"};
const std::string_view kFRESignInSecondaryActionLabelUpdateParamStaySignedOut =
"StaySignedOut";
BASE_FEATURE(kFRESignInSecondaryActionLabelUpdate,
base::FEATURE_ENABLED_BY_DEFAULT);
bool FRESignInSecondaryActionLabelUpdate() {
return base::FeatureList::IsEnabled(kFRESignInSecondaryActionLabelUpdate);
}
BASE_FEATURE(kConfirmationButtonSwapOrder, base::FEATURE_DISABLED_BY_DEFAULT);
bool IsConfirmationButtonSwapOrderEnabled() {
return base::FeatureList::IsEnabled(kConfirmationButtonSwapOrder);
}
BASE_FEATURE(kIOSPushNotificationMultiProfile,
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(kFullscreenTransitionSpeed, base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(kRefactorToolbarsSize, base::FEATURE_DISABLED_BY_DEFAULT);
bool IsRefactorToolbarsSize() {
return base::FeatureList::IsEnabled(kRefactorToolbarsSize);
}
BASE_FEATURE(kNewShareExtension, base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(kIPHAblation, base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(kLensOverlayDisableIPHPanGesture,
base::FEATURE_ENABLED_BY_DEFAULT);
bool IsIPHAblationEnabled() {
return base::FeatureList::IsEnabled(kIPHAblation);
}
BASE_FEATURE(kIPHGestureRecognitionAblation, 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(kNonModalSignInPromo, base::FEATURE_ENABLED_BY_DEFAULT);
bool IsNonModalSignInPromoEnabled() {
return base::FeatureList::IsEnabled(kNonModalSignInPromo);
}
BASE_FEATURE(kIOSOneTapMiniMapRestrictions, 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(kIOSOneTapMiniMapRemoveSectionsBreaks,
base::FEATURE_ENABLED_BY_DEFAULT);
BASE_FEATURE(kIOSMiniMapUniversalLink, base::FEATURE_DISABLED_BY_DEFAULT);
bool IsNotificationCollisionManagementEnabled() {
return base::FeatureList::IsEnabled(kNotificationCollisionManagement);
}
BASE_FEATURE(kNotificationCollisionManagement,
base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(kIOSProvidesAppNotificationSettings,
base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(kSignInButtonNoAvatar, base::FEATURE_ENABLED_BY_DEFAULT);
bool IsSignInButtonNoAvatarEnabled() {
return base::FeatureList::IsEnabled(kSignInButtonNoAvatar);
}
BASE_FEATURE(kNTPBackgroundCustomization, base::FEATURE_DISABLED_BY_DEFAULT);
bool IsNTPBackgroundCustomizationEnabled() {
return base::FeatureList::IsEnabled(kNTPBackgroundCustomization);
}
constexpr base::FeatureParam<int> kMaxRecentlyUsedBackgrounds{
&kNTPBackgroundCustomization,
/*name=*/"max-recently-used-backgrounds", /*default_value=*/7};
int MaxRecentlyUsedBackgrounds() {
return kMaxRecentlyUsedBackgrounds.Get();
}
BASE_FEATURE(kNTPBackgroundColorSlider, base::FEATURE_DISABLED_BY_DEFAULT);
bool IsNTPBackgroundColorSliderEnabled() {
return base::FeatureList::IsEnabled(kNTPBackgroundColorSlider);
}
BASE_FEATURE(kRunDefaultStatusCheck, base::FEATURE_ENABLED_BY_DEFAULT);
bool IsRunDefaultStatusCheckEnabled() {
return base::FeatureList::IsEnabled(kRunDefaultStatusCheck);
}
BASE_FEATURE(kBestOfAppFRE, 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(kFeedbackIncludeGWSVariations, base::FEATURE_ENABLED_BY_DEFAULT);
bool IsFeedbackIncludeGWSVariationsEnabled() {
return base::FeatureList::IsEnabled(kFeedbackIncludeGWSVariations);
}
bool IsDefaultBrowserPromoPropensityModelEnabled() {
return base::FeatureList::IsEnabled(
segmentation_platform::features::kDefaultBrowserPromoPropensityModel);
}
BASE_FEATURE(kIOSTrustedVaultNotification, base::FEATURE_DISABLED_BY_DEFAULT);
bool IsIOSTrustedVaultNotificationEnabled() {
return base::FeatureList::IsEnabled(kIOSTrustedVaultNotification);
}
BASE_FEATURE(kDiamondPrototype, base::FEATURE_DISABLED_BY_DEFAULT);
bool IsDiamondPrototypeEnabled() {
if (ui::GetDeviceFormFactor() != ui::DEVICE_FORM_FACTOR_PHONE) {
return false;
}
return base::FeatureList::IsEnabled(kDiamondPrototype);
}
BASE_FEATURE(kIOSDefaultBrowserOffCyclePromo,
base::FEATURE_DISABLED_BY_DEFAULT);
bool IsDefaultBrowserOffCyclePromoEnabled() {
if (@available(iOS 18.3, *)) {
return base::FeatureList::IsEnabled(kIOSDefaultBrowserOffCyclePromo);
}
return false;
}
BASE_FEATURE(kIOSLogInstallAttribution, base::FEATURE_ENABLED_BY_DEFAULT);
bool IsInstallAttributionLoggingEnabled() {
return base::FeatureList::IsEnabled(kIOSLogInstallAttribution);
}
BASE_FEATURE(kIOSLogAppPreviewInstallAttribution,
base::FEATURE_ENABLED_BY_DEFAULT);
bool IsAppPreviewInstallAttributionLoggingEnabled() {
return base::FeatureList::IsEnabled(kIOSLogAppPreviewInstallAttribution);
}
BASE_FEATURE(kIOSUseDefaultAppsDestinationForPromos,
base::FEATURE_DISABLED_BY_DEFAULT);
bool IsDefaultAppsDestinationAvailable() {
if (@available(iOS 18.3, *)) {
return true;
}
return false;
}
bool IsUseDefaultAppsDestinationForPromosEnabled() {
return base::FeatureList::IsEnabled(kIOSUseDefaultAppsDestinationForPromos);
}
BASE_FEATURE(kSynchronousEditMenuItems, base::FEATURE_ENABLED_BY_DEFAULT);
bool ShouldShowEditMenuItemsSynchronously() {
if (@available(iOS 26, *)) {
return base::FeatureList::IsEnabled(kSynchronousEditMenuItems);
}
return false;
}
BASE_FEATURE(kIOSTipsNotificationsAlternativeStrings,
base::FEATURE_DISABLED_BY_DEFAULT);
bool IsTipsNotificationsAlternativeStringsEnabled() {
return base::FeatureList::IsEnabled(kIOSTipsNotificationsAlternativeStrings);
}
const char kTipsNotificationsAlternativeStringVersion[] =
"TipsNotificationsAlternativeStringVersion";
TipsNotificationsAlternativeStringVersion
GetTipsNotificationsAlternativeStringVersion() {
return static_cast<TipsNotificationsAlternativeStringVersion>(
base::GetFieldTrialParamByFeatureAsInt(
kIOSTipsNotificationsAlternativeStrings,
kTipsNotificationsAlternativeStringVersion,
/*default_value=*/
static_cast<int>(
TipsNotificationsAlternativeStringVersion::kDefault)));
}
BASE_FEATURE(kImportPasswordsFromSafari, base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(kIOSSyncedSetUp, base::FEATURE_DISABLED_BY_DEFAULT);
bool IsSyncedSetUpEnabled() {
return base::FeatureList::IsEnabled(
sync_preferences::features::kEnableCrossDevicePrefTracker) &&
base::FeatureList::IsEnabled(kIOSSyncedSetUp);
}
BASE_FEATURE(kMultilineBrowserOmnibox, base::FEATURE_DISABLED_BY_DEFAULT);
const char kMultilineOmniboxParam[] = "kMultilineOmniboxParam";
const char kMultilineOmniboxAllText[] = "kMultilineOmniboxAllText";
const char kMultilineOmniboxNoPeeking[] = "kMultilineOmniboxNoPeeking";
const char kMultilineOmniboxHalfLinePeeking[] =
"kMultilineOmniboxHalfLinePeeking";
const char kMultilineOmniboxFullLineAndPeeking[] =
"kMultilineOmniboxFullLineAndPeeking";
bool IsMultilineBrowserOmniboxEnabled() {
if (ui::GetDeviceFormFactor() != ui::DEVICE_FORM_FACTOR_PHONE) {
return false;
}
return base::FeatureList::IsEnabled(kMultilineBrowserOmnibox);
}
// Peeking values for MultilineOmnibox.
const float kMultilineOmniboxNoPeekingValue = 0.0f;
const float kMultilineOmniboxHalfLinePeekingValue = 0.5f;
const float kMultilineOmniboxFullLineAndPeekingValue = 1.5f;
CGFloat GetMultilineOmniboxAutocompleteHeight() {
if (!base::FeatureList::IsEnabled(kMultilineBrowserOmnibox)) {
return CGFLOAT_MAX;
}
std::string param_value = base::GetFieldTrialParamByFeatureAsString(
kMultilineBrowserOmnibox, kMultilineOmniboxParam,
kMultilineOmniboxAllText);
if (param_value == kMultilineOmniboxNoPeeking) {
return kMultilineOmniboxNoPeekingValue;
} else if (param_value == kMultilineOmniboxHalfLinePeeking) {
return kMultilineOmniboxHalfLinePeekingValue;
} else if (param_value == kMultilineOmniboxFullLineAndPeeking) {
return kMultilineOmniboxFullLineAndPeekingValue;
}
// Default case if the param is not recognized or is kMultilineOmniboxAllText.
return CGFLOAT_MAX;
}
BASE_FEATURE(kIOSAutoOpenRemoteTabGroupsSettings,
base::FEATURE_DISABLED_BY_DEFAULT);
bool IsAutoOpenRemoteTabGroupsSettingsFeatureEnabled() {
return base::FeatureList::IsEnabled(kIOSAutoOpenRemoteTabGroupsSettings);
}
BASE_FEATURE(kDisableKeyboardAccessory, base::FEATURE_DISABLED_BY_DEFAULT);
const char kDisableKeyboardAccessoryParam[] = "kDisableKeyboardAccessoryParam";
const char kDisableKeyboardAccessoryOnlySymbols[] =
"kDisableKeyboardAccessoryOnlySymbols";
const char kDisableKeyboardAccessoryOnlyFeatures[] =
"kDisableKeyboardAccessoryOnlyFeatures";
const char kDisableKeyboardAccessoryCompletely[] =
"kDisableKeyboardAccessoryCompletely";
bool ShouldShowKeyboardAccessory() {
if (!base::FeatureList::IsEnabled(kDisableKeyboardAccessory)) {
return true;
}
std::string feature_param = base::GetFieldTrialParamValueByFeature(
kDisableKeyboardAccessory, kDisableKeyboardAccessoryParam);
return feature_param != kDisableKeyboardAccessoryCompletely;
}
bool ShouldShowKeyboardAccessorySymbols() {
if (!base::FeatureList::IsEnabled(kDisableKeyboardAccessory)) {
return true;
}
std::string feature_param = base::GetFieldTrialParamValueByFeature(
kDisableKeyboardAccessory, kDisableKeyboardAccessoryParam);
return feature_param == kDisableKeyboardAccessoryOnlySymbols;
}
bool ShouldShowKeyboardAccessoryFeatures() {
if (!base::FeatureList::IsEnabled(kDisableKeyboardAccessory)) {
return true;
}
std::string feature_param = base::GetFieldTrialParamValueByFeature(
kDisableKeyboardAccessory, kDisableKeyboardAccessoryParam);
return feature_param == kDisableKeyboardAccessoryOnlyFeatures;
}
BASE_FEATURE(kLocationBarBadgeMigration, base::FEATURE_DISABLED_BY_DEFAULT);
bool IsLocationBarBadgeMigrationEnabled() {
return base::FeatureList::IsEnabled(kLocationBarBadgeMigration);
}
BASE_FEATURE(kIOSFusebox, base::FEATURE_DISABLED_BY_DEFAULT);
bool IsIOSFuseboxEnabled() {
return base::FeatureList::IsEnabled(kIOSFusebox);
}