| // Copyright 2023 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef CHROME_BROWSER_UI_HATS_SURVEY_CONFIG_H_ |
| #define CHROME_BROWSER_UI_HATS_SURVEY_CONFIG_H_ |
| |
| #include <optional> |
| #include <string> |
| #include <vector> |
| |
| #include "base/feature_list.h" |
| #include "base/time/time.h" |
| #include "build/branding_buildflags.h" |
| #include "components/compose/buildflags.h" |
| #include "pdf/buildflags.h" |
| |
| #if !BUILDFLAG(IS_ANDROID) |
| // Trigger identifiers currently used; duplicates not allowed. |
| extern const char kHatsSurveyTriggerAutofillAddress[]; |
| extern const char kHatsSurveyTriggerAutofillAddressUserPerception[]; |
| extern const char kHatsSurveyTriggerAutofillAddressUserDeclinedSuggestion[]; |
| extern const char kHatsSurveyTriggerAutofillAddressUserDeclinedSave[]; |
| extern const char kHatsSurveyTriggerAutofillCreditCardUserPerception[]; |
| extern const char kHatsSurveyTriggerAutofillPasswordUserPerception[]; |
| extern const char kHatsSurveyTriggerAutofillCard[]; |
| extern const char kHatsSurveyTriggerAutofillPassword[]; |
| extern const char kHatsSurveyTriggerDownloadWarningBubbleBypass[]; |
| extern const char kHatsSurveyTriggerDownloadWarningBubbleHeed[]; |
| extern const char kHatsSurveyTriggerDownloadWarningBubbleIgnore[]; |
| extern const char kHatsSurveyTriggerDownloadWarningPageBypass[]; |
| extern const char kHatsSurveyTriggerDownloadWarningPageHeed[]; |
| extern const char kHatsSurveyTriggerDownloadWarningPageIgnore[]; |
| extern const char kHatsSurveyTriggerHistoryEmbeddings[]; |
| extern const char kHatsSurveyTriggerIdentityAddressBubbleSignin[]; |
| extern const char kHatsSurveyTriggerIdentityDiceWebSigninAccepted[]; |
| extern const char kHatsSurveyTriggerIdentityDiceWebSigninDeclined[]; |
| extern const char kHatsSurveyTriggerIdentityFirstRunSignin[]; |
| extern const char kHatsSurveyTriggerIdentityPasswordBubbleSignin[]; |
| extern const char kHatsSurveyTriggerIdentityProfileMenuDismissed[]; |
| extern const char kHatsSurveyTriggerIdentityProfileMenuSignin[]; |
| extern const char kHatsSurveyTriggerIdentityProfilePickerAddProfileSignin[]; |
| extern const char kHatsSurveyTriggerIdentitySigninInterceptProfileSeparation[]; |
| extern const char kHatsSurveyTriggerIdentitySigninPromoBubbleDismissed[]; |
| extern const char kHatsSurveyTriggerIdentitySwitchProfileFromProfileMenu[]; |
| extern const char kHatsSurveyTriggerIdentitySwitchProfileFromProfilePicker[]; |
| extern const char kHatsSurveyTriggerLensOverlayResults[]; |
| extern const char kHatsSurveyTriggerNtpModules[]; |
| extern const char kHatsSurveyTriggerNtpPhotosModuleOptOut[]; |
| extern const char kHatsSurveyTriggerPasswordChangeCanceled[]; |
| extern const char kHatsSurveyTriggerPasswordChangeDelayed[]; |
| extern const char kHatsSurveyTriggerPasswordChangeError[]; |
| extern const char kHatsSurveyTriggerPasswordChangeSuccess[]; |
| extern const char kHatsSurveyTriggerPerformanceControlsPPM[]; |
| extern const char kHatsSurveyTriggerPrivacyGuide[]; |
| extern const char kHatsSurveyTriggerRedWarning[]; |
| extern const char kHatsSurveyTriggerSafetyHubOneOffExperimentControl[]; |
| extern const char kHatsSurveyTriggerSafetyHubOneOffExperimentNotification[]; |
| extern const char kHatsSurveyTriggerSafetyHubOneOffExperimentInteraction[]; |
| extern const char kHatsSurveyTriggerSettings[]; |
| extern const char kHatsSurveyTriggerSettingsPrivacy[]; |
| extern const char kHatsSurveyTriggerSettingsSecurity[]; |
| extern const char kHatsSurveyTriggerTrustSafetyPrivacySettings[]; |
| extern const char kHatsSurveyTriggerTrustSafetyTrustedSurface[]; |
| extern const char kHatsSurveyTriggerTrustSafetyTransactions[]; |
| extern const char kHatsSurveyTriggerTrustSafetyV2BrowsingData[]; |
| extern const char kHatsSurveyTriggerTrustSafetyV2ControlGroup[]; |
| extern const char kHatsSurveyTriggerTrustSafetyV2DownloadWarningUI[]; |
| extern const char kHatsSurveyTriggerTrustSafetyV2PasswordCheck[]; |
| extern const char kHatsSurveyTriggerTrustSafetyV2PasswordProtectionUI[]; |
| extern const char kHatsSurveyTriggerTrustSafetyV2SafetyCheck[]; |
| extern const char kHatsSurveyTriggerTrustSafetyV2SafetyHubNotification[]; |
| extern const char kHatsSurveyTriggerTrustSafetyV2SafetyHubInteraction[]; |
| extern const char kHatsSurveyTriggerTrustSafetyV2TrustedSurface[]; |
| extern const char kHatsSurveyTriggerTrustSafetyV2PrivacyGuide[]; |
| extern const char kHatsSurveyTriggerTrustSafetyV2SafeBrowsingInterstitial[]; |
| extern const char kHatsSurveyTriggerWallpaperSearch[]; |
| #if BUILDFLAG(ENABLE_COMPOSE) |
| extern const char kHatsSurveyTriggerComposeAcceptance[]; |
| extern const char kHatsSurveyTriggerComposeClose[]; |
| extern const char kHatsSurveyTriggerComposeNudgeClose[]; |
| #endif // BUILDFLAG(ENABLE_COMPOSE) |
| extern const char kHatsSurveyTriggerWhatsNew[]; |
| #else |
| extern const char kHatsSurveyTriggerAndroidStartupSurvey[]; |
| extern const char kHatsSurveyTriggerQuickDelete[]; |
| extern const char kHatsSurveyTriggerClearBrowsingData[]; |
| extern const char kHatsSurveyTriggerSafetyHubAndroid[]; |
| extern const char kHatsSurveyOrganicTriggerSafetyHubAndroid[]; |
| #endif // #if !BUILDFLAG(IS_ANDROID) |
| |
| #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) |
| extern const char kHatsSurveyTriggerPrivacySandboxWhatsNewSurvey[]; |
| #endif // BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) |
| |
| extern const char kHatsSurveyTriggerPermissionsPrompt[]; |
| extern const char kHatsSurveyTriggerPlusAddressAcceptedFirstTimeCreate[]; |
| extern const char kHatsSurveyTriggerPlusAddressCreatedMultiplePlusAddresses[]; |
| extern const char |
| kHatsSurveyTriggerPlusAddressCreatedPlusAddressViaManualFallback[]; |
| extern const char kHatsSurveyTriggerPlusAddressDeclinedFirstTimeCreate[]; |
| extern const char |
| kHatsSurveyTriggerPlusAddressDidChooseEmailOverPlusAddressSurvey[]; |
| extern const char |
| kHatsSurveyTriggerPlusAddressDidChoosePlusAddressOverEmailSurvey[]; |
| extern const char |
| kHatsSurveyTriggerPlusAddressFilledPlusAddressViaManualFallback[]; |
| extern const char kHatsSurveyTriggerPrivacySandboxSentimentSurvey[]; |
| extern const char kHatsSurveyTriggerPrivacySandboxActSurvey[]; |
| extern const char kHatsSurveyTriggerMerchantTrustEvaluationControlSurvey[]; |
| extern const char kHatsSurveyTriggerMerchantTrustEvaluationExperimentSurvey[]; |
| extern const char kHatsSurveyTriggerMerchantTrustLearnSurvey[]; |
| extern const char kHatsSurveyTriggerOnFocusZpsSuggestionsHappiness[]; |
| extern const char kHatsSurveyTriggerOnFocusZpsSuggestionsUtility[]; |
| |
| #if BUILDFLAG(ENABLE_PDF_SAVE_TO_DRIVE) |
| extern const char kHatsSurveyTriggerPdfSaveToDrive[]; |
| #endif // BUILDFLAG(ENABLE_PDF_SAVE_TO_DRIVE) |
| |
| extern const char kHatsSurveyTriggerTesting[]; |
| // The Trigger ID for a test HaTS Next survey which is available for testing |
| // and demo purposes when the migration feature flag is enabled. |
| extern const char kHatsNextSurveyTriggerIDTesting[]; |
| |
| class Profile; |
| |
| namespace hats { |
| struct SurveyConfig { |
| // LINT.IfChange(RequestedBrowserType) |
| enum RequestedBrowserType { |
| // A standard survey, shown only in regular mode. |
| kRegular = 0, |
| // An Incognito survey, shown only in incognito. |
| kIncognito = 1, |
| }; |
| // LINT.ThenChange(//chrome/browser/ui/android/hats/java/src/org/chromium/chrome/browser/ui/hats/SurveyConfig.java:RequestedBrowserType) |
| |
| // Constructs a SurveyConfig by inspecting |feature|. This includes checking |
| // if the feature is enabled, as well as inspecting the feature parameters |
| // for the survey probability, and if |presupplied_trigger_id| is not |
| // provided, the trigger ID. To pass any product specific data for the |
| // survey, configure fields here, matches are CHECK enforced. |
| // SurveyConfig that enable |log_responses_to_uma| and/or |
| // |log_responses_to_ukm| will need to have surveys reviewed by privacy to |
| // ensure they are appropriate to log to UMA and/or UKM. This is enforced |
| // through the OWNERS mechanism. |
| SurveyConfig( |
| const base::Feature* feature, |
| const std::string& trigger, |
| const std::optional<std::string>& presupplied_trigger_id = std::nullopt, |
| const std::vector<std::string>& product_specific_bits_data_fields = {}, |
| const std::vector<std::string>& product_specific_string_data_fields = {}, |
| bool log_responses_to_uma = false, |
| bool log_responses_to_ukm = false, |
| RequestedBrowserType requested_browser_type = |
| RequestedBrowserType::kRegular); |
| |
| SurveyConfig(); |
| SurveyConfig(const SurveyConfig&); |
| ~SurveyConfig(); |
| |
| // Whether the survey is currently enabled and can be shown. |
| bool enabled = false; |
| |
| // Probability [0,1] of how likely a chosen user will see the survey. |
| double probability = 0.0f; |
| |
| // The trigger for this survey within the browser. |
| std::string trigger; |
| |
| // Trigger ID for the survey. |
| std::string trigger_id; |
| |
| // Histogram name for the survey. |
| std::optional<std::string> hats_histogram_name; |
| |
| // ID that ties Chrome survey configuration to UKM. This ID can be configured |
| // in Finch to any 64-bit unsigned integer. This ID should only be used to |
| // distinguish surveys in UKM and no other purpose. |
| std::optional<uint64_t> hats_survey_ukm_id; |
| |
| // The survey will prompt every time because the user has explicitly decided |
| // to take the survey e.g. clicking a link. |
| bool user_prompted = false; |
| |
| // Product Specific Bit Data fields which are sent with the survey |
| // response. |
| std::vector<std::string> product_specific_bits_data_fields; |
| |
| // Product Specific String Data fields which are sent with the survey |
| // response. |
| std::vector<std::string> product_specific_string_data_fields; |
| |
| // Requested browser type decides where the survey can be shown. |
| RequestedBrowserType requested_browser_type = RequestedBrowserType::kRegular; |
| |
| // The feature associated with the HaTS survey. It is used to check if the |
| // survey is in the dogfood stage, meaning that it's launched only for a |
| // subset of users controlled by some Google group. |
| raw_ptr<const base::Feature> survey_feature; |
| |
| // Returns |hats_histogram_name| if |hats_histogram_name| is an non-empty |
| // std::string that is prefixed with Feedback.HappinessTrackingSurvey. |
| // Otherwise, returns std::nullopt. |
| static std::optional<std::string> ValidateHatsHistogramName( |
| const std::optional<std::string>& hats_histogram_name); |
| |
| // Returns |hats_survey_ukm_id| if |hats_survey_ukm_id| is an non-empty |
| // optional greater than 0. Otherwise, returns std::nullopt. |
| static std::optional<uint64_t> ValidateHatsSurveyUkmId( |
| const std::optional<uint64_t> hats_survey_ukm_id); |
| |
| // Initializes the cooldown period override for this survey config if |
| // `cooldown_period_override` is not zero. |
| void SetCooldownPeriodOverride( |
| const base::TimeDelta& cooldown_period_override); |
| |
| // Returns the cooldown override for this survey only if the survey feature |
| // is enabled for the current profile and the feature is in the dogfood stage, |
| // i.e. it's controlled by some Google group. |
| std::optional<base::TimeDelta> GetCooldownPeriodOverride( |
| Profile* profile) const; |
| |
| // A convenience method to check if the survey config has an effective |
| // cooldown override period. |
| bool IsCooldownOverrideEnabled(Profile* profile) const; |
| |
| private: |
| // Overrides the default time between a user seeing a survey and being able to |
| // see it again. When this value is non-zero, the date when other survey |
| // impressions happened is ignored. This value should not be used directly |
| // because the cooldown period override should be effective only if the survey |
| // feature is launched for a specific Google group, see |
| // `IsCooldownOverrideEnabled()`. |
| // TODO: crbug.com/348137782 - Either make this a global constant or add a |
| // verification logic that no 2 different cooldown period overrides are |
| // configured. |
| std::optional<base::TimeDelta> cooldown_period_override_; |
| }; |
| |
| using SurveyConfigs = base::flat_map<std::string, SurveyConfig>; |
| // Get the list of active ongoing surveys and store into |
| // |survey_configs_by_triggers_|. |
| void GetActiveSurveyConfigs(SurveyConfigs& survey_configs_by_triggers_); |
| |
| } // namespace hats |
| |
| #endif // CHROME_BROWSER_UI_HATS_SURVEY_CONFIG_H_ |