blob: 16add62f45c2cf8adf0a8e7a57460a2c72dc516a [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.
#include "chrome/browser/ui/webui/welcome/helpers.h"
#include <string>
#include <vector>
#include "base/containers/contains.h"
#include "base/feature_list.h"
#include "base/metrics/field_trial_params.h"
#include "base/ranges/algorithm.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/values.h"
#include "build/branding_buildflags.h"
#include "build/build_config.h"
#include "chrome/browser/policy/browser_signin_policy_handler.h"
#include "chrome/browser/policy/profile_policy_connector.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/search/search.h"
#include "components/policy/core/common/policy_map.h"
#include "components/policy/policy_constants.h"
namespace welcome {
// Available modules for both new and returning users.
const char kDefaultNewUserModules[] =
"nux-google-apps,nux-ntp-background,nux-set-as-default,signin-view";
const char kDefaultReturningUserModules[] = "nux-set-as-default";
// Feature flag.
BASE_FEATURE(kFeature, "NuxOnboarding", base::FEATURE_ENABLED_BY_DEFAULT);
// For testing purposes
BASE_FEATURE(kForceEnabled,
"NuxOnboardingForceEnabled",
base::FEATURE_DISABLED_BY_DEFAULT);
// The value of these FeatureParam values should be a comma-delimited list
// of element names allowlisted in the MODULES_WHITELIST list, defined in
// chrome/browser/resources/welcome/welcome_app.js
const base::FeatureParam<std::string> kNewUserModules{
&kFeature, "new-user-modules", kDefaultNewUserModules};
const base::FeatureParam<std::string> kReturningUserModules{
&kFeature, "returning-user-modules", kDefaultReturningUserModules};
// For testing purposes
const base::FeatureParam<std::string> kForceEnabledNewUserModules = {
&kForceEnabled, "new-user-modules", kDefaultNewUserModules};
const base::FeatureParam<std::string> kForceEnabledReturningUserModules = {
&kForceEnabled, "returning-user-modules", kDefaultReturningUserModules};
// FeatureParam for app variation.
const base::FeatureParam<bool> kShowGoogleApp{&kFeature,
"app-variation-enabled", false};
// For testing purposes
const base::FeatureParam<bool> kForceEnabledShowGoogleApp = {
&kForceEnabled, "app-variation-enabled", false};
bool IsPolicySetAndFalse(const policy::PolicyMap& policies,
const std::string& policy_name) {
const base::Value* policy =
policies.GetValue(policy_name, base::Value::Type::BOOLEAN);
return policy && !policy->GetBool();
}
bool CanShowGoogleAppModule(const policy::PolicyMap& policies) {
if (IsPolicySetAndFalse(policies, policy::key::kBookmarkBarEnabled))
return false;
if (IsPolicySetAndFalse(policies, policy::key::kEditBookmarksEnabled))
return false;
return true;
}
bool CanShowNTPBackgroundModule(const policy::PolicyMap& policies,
Profile* profile) {
// We can't set the background if the NTP is something other than Google.
return !policies.GetValue(policy::key::kNewTabPageLocation,
base::Value::Type::STRING) &&
search::DefaultSearchProviderIsGoogle(profile);
}
bool CanShowSetDefaultModule(const policy::PolicyMap& policies) {
if (IsPolicySetAndFalse(policies, policy::key::kDefaultBrowserSettingEnabled))
return false;
return true;
}
bool CanShowSigninModule(const policy::PolicyMap& policies) {
const base::Value* browser_signin_value = policies.GetValue(
policy::key::kBrowserSignin, base::Value::Type::INTEGER);
if (!browser_signin_value)
return true;
return static_cast<policy::BrowserSigninMode>(
browser_signin_value->GetInt()) !=
policy::BrowserSigninMode::kDisabled;
}
// Welcome experiments depend on Google being the default search provider.
static bool CanExperimentWithVariations(Profile* profile) {
return search::DefaultSearchProviderIsGoogle(profile);
}
bool IsEnabled(Profile* profile) {
#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
return base::FeatureList::IsEnabled(welcome::kFeature) ||
base::FeatureList::IsEnabled(welcome::kForceEnabled);
#else
// Allow enabling outside official builds for testing purposes.
return base::FeatureList::IsEnabled(welcome::kForceEnabled);
#endif // BUILDFLAG(GOOGLE_CHROME_BRANDING)
}
bool IsAppVariationEnabled() {
return kForceEnabledShowGoogleApp.Get() || kShowGoogleApp.Get();
}
const policy::PolicyMap& GetPoliciesFromProfile(Profile* profile) {
policy::ProfilePolicyConnector* profile_connector =
profile->GetProfilePolicyConnector();
DCHECK(profile_connector);
return profile_connector->policy_service()->GetPolicies(
policy::PolicyNamespace(policy::POLICY_DOMAIN_CHROME, std::string()));
}
std::vector<std::string> GetAvailableModules(Profile* profile) {
const policy::PolicyMap& policies = GetPoliciesFromProfile(profile);
std::vector<std::string> available_modules;
if (CanShowGoogleAppModule(policies))
available_modules.push_back("nux-google-apps");
if (CanShowNTPBackgroundModule(policies, profile))
available_modules.push_back("nux-ntp-background");
if (CanShowSetDefaultModule(policies))
available_modules.push_back("nux-set-as-default");
if (CanShowSigninModule(policies))
available_modules.push_back("signin-view");
return available_modules;
}
std::string FilterModules(const std::string& requested_modules,
const std::vector<std::string>& available_modules) {
std::vector<std::string> filtered_modules;
base::ranges::copy_if(
base::SplitString(requested_modules, ",", base::TRIM_WHITESPACE,
base::SPLIT_WANT_NONEMPTY),
std::back_inserter(filtered_modules),
[&available_modules](const std::string& module) {
return !module.empty() && base::Contains(available_modules, module);
});
return base::JoinString(filtered_modules, ",");
}
base::Value::Dict GetModules(Profile* profile) {
// This function should not be called when feature is not on.
DCHECK(welcome::IsEnabled(profile));
std::string new_user_modules = kDefaultNewUserModules;
std::string returning_user_modules = kDefaultReturningUserModules;
if (base::FeatureList::IsEnabled(welcome::kForceEnabled)) {
new_user_modules = kForceEnabledNewUserModules.Get();
returning_user_modules = kForceEnabledReturningUserModules.Get();
} else if (CanExperimentWithVariations(profile)) {
new_user_modules = kNewUserModules.Get();
returning_user_modules = kReturningUserModules.Get();
}
std::vector<std::string> available_modules = GetAvailableModules(profile);
base::Value::Dict modules;
modules.Set("new-user", FilterModules(new_user_modules, available_modules));
modules.Set("returning-user",
FilterModules(returning_user_modules, available_modules));
return modules;
}
bool CanShowGoogleAppModuleForTesting(const policy::PolicyMap& policies) {
return CanShowGoogleAppModule(policies);
}
bool CanShowNTPBackgroundModuleForTesting(const policy::PolicyMap& policies,
Profile* profile) {
return CanShowNTPBackgroundModule(policies, profile);
}
bool CanShowSetDefaultModuleForTesting(const policy::PolicyMap& policies) {
return CanShowSetDefaultModule(policies);
}
bool CanShowSigninModuleForTesting(const policy::PolicyMap& policies) {
return CanShowSigninModule(policies);
}
} // namespace welcome