| // Copyright 2017 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "android_webview/browser/aw_feature_list_creator.h" |
| |
| #include <memory> |
| #include <set> |
| #include <string> |
| #include <utility> |
| #include <vector> |
| |
| #include "android_webview/browser/aw_browser_context.h" |
| #include "android_webview/browser/aw_browser_policy_connector.h" |
| #include "android_webview/browser/aw_metrics_service_client.h" |
| #include "android_webview/browser/aw_variations_seed_bridge.h" |
| #include "android_webview/browser/net/aw_url_request_context_getter.h" |
| #include "base/base_switches.h" |
| #include "base/bind_helpers.h" |
| #include "base/command_line.h" |
| #include "base/feature_list.h" |
| #include "base/path_service.h" |
| #include "base/strings/string_split.h" |
| #include "base/time/time.h" |
| #include "cc/base/switches.h" |
| #include "components/autofill/core/common/autofill_prefs.h" |
| #include "components/metrics/metrics_pref_names.h" |
| #include "components/metrics/metrics_service.h" |
| #include "components/policy/core/browser/configuration_policy_pref_store.h" |
| #include "components/policy/core/browser/url_blacklist_manager.h" |
| #include "components/pref_registry/pref_registry_syncable.h" |
| #include "components/prefs/in_memory_pref_store.h" |
| #include "components/prefs/json_pref_store.h" |
| #include "components/prefs/pref_registry_simple.h" |
| #include "components/prefs/pref_service.h" |
| #include "components/prefs/pref_service_factory.h" |
| #include "components/variations/entropy_provider.h" |
| #include "components/variations/pref_names.h" |
| #include "components/variations/service/safe_seed_manager.h" |
| #include "components/variations/service/variations_service.h" |
| #include "services/preferences/tracked/segregated_pref_store.h" |
| |
| namespace android_webview { |
| |
| namespace { |
| |
| // These prefs go in the JsonPrefStore, and will persist across runs. Other |
| // prefs go in the InMemoryPrefStore, and will be lost when the process ends. |
| const char* const kPersistentPrefsWhitelist[] = { |
| // Random seed value for variation's entropy providers, used to assign |
| // experiment groups. |
| metrics::prefs::kMetricsLowEntropySource, |
| // Used by CachingPermutedEntropyProvider to cache generated values. |
| variations::prefs::kVariationsPermutedEntropyCache, |
| }; |
| |
| // Shows notifications which correspond to PersistentPrefStore's reading errors. |
| void HandleReadError(PersistentPrefStore::PrefReadError error) {} |
| |
| base::FilePath GetPrefStorePath() { |
| base::FilePath path; |
| base::PathService::Get(base::DIR_ANDROID_APP_DATA, &path); |
| path = path.Append(FILE_PATH_LITERAL("pref_store")); |
| return path; |
| } |
| |
| std::unique_ptr<PrefService> CreatePrefService( |
| policy::BrowserPolicyConnectorBase* browser_policy_connector) { |
| auto pref_registry = base::MakeRefCounted<user_prefs::PrefRegistrySyncable>(); |
| // We only use the autocomplete feature of Autofill, which is controlled via |
| // the manager_delegate. We don't use the rest of Autofill, which is why it is |
| // hardcoded as disabled here. |
| // TODO(crbug.com/873740): The following also disables autocomplete. |
| // Investigate what the intended behavior is. |
| pref_registry->RegisterBooleanPref(autofill::prefs::kAutofillProfileEnabled, |
| false); |
| pref_registry->RegisterBooleanPref( |
| autofill::prefs::kAutofillCreditCardEnabled, false); |
| policy::URLBlacklistManager::RegisterProfilePrefs(pref_registry.get()); |
| |
| pref_registry->RegisterStringPref( |
| android_webview::prefs::kWebRestrictionsAuthority, std::string()); |
| |
| android_webview::AwURLRequestContextGetter::RegisterPrefs( |
| pref_registry.get()); |
| metrics::MetricsService::RegisterPrefs(pref_registry.get()); |
| variations::VariationsService::RegisterPrefs(pref_registry.get()); |
| safe_browsing::RegisterProfilePrefs(pref_registry.get()); |
| |
| PrefServiceFactory pref_service_factory; |
| |
| std::set<std::string> persistent_prefs; |
| for (const char* const pref_name : kPersistentPrefsWhitelist) |
| persistent_prefs.insert(pref_name); |
| |
| // SegregatedPrefStore may be validated with a MAC (message authentication |
| // code). On Android, the store is protected by app sandboxing, so validation |
| // is unnnecessary. Thus validation_delegate is null. |
| pref_service_factory.set_user_prefs(base::MakeRefCounted<SegregatedPrefStore>( |
| base::MakeRefCounted<InMemoryPrefStore>(), |
| base::MakeRefCounted<JsonPrefStore>(GetPrefStorePath()), persistent_prefs, |
| /*validation_delegate=*/nullptr)); |
| pref_service_factory.set_managed_prefs( |
| base::MakeRefCounted<policy::ConfigurationPolicyPrefStore>( |
| browser_policy_connector, |
| browser_policy_connector->GetPolicyService(), |
| browser_policy_connector->GetHandlerList(), |
| policy::POLICY_LEVEL_MANDATORY)); |
| pref_service_factory.set_read_error_callback( |
| base::BindRepeating(&HandleReadError)); |
| |
| return pref_service_factory.Create(pref_registry); |
| } |
| |
| } // namespace |
| |
| AwFeatureListCreator::AwFeatureListCreator() |
| : aw_field_trials_(std::make_unique<AwFieldTrials>()) {} |
| |
| AwFeatureListCreator::~AwFeatureListCreator() {} |
| |
| void AwFeatureListCreator::SetUpFieldTrials() { |
| auto* metrics_client = AwMetricsServiceClient::GetInstance(); |
| |
| // Chrome uses the default entropy provider here (rather than low entropy |
| // provider). The default provider needs to know whether UMA is enabled, but |
| // WebView determines UMA by querying GMS, which is very slow. So WebView |
| // always uses the low entropy provider. Both providers guarantee permanent |
| // consistency, which is the main requirement. The difference is that the low |
| // entropy provider has fewer unique experiment combinations. This is better |
| // for privacy (since experiment state doesn't identify users), but also means |
| // fewer combinations tested in the wild. |
| DCHECK(!field_trial_list_); |
| field_trial_list_ = std::make_unique<base::FieldTrialList>( |
| metrics_client->CreateLowEntropyProvider()); |
| |
| variations::UIStringOverrider ui_string_overrider; |
| client_ = std::make_unique<AwVariationsServiceClient>(); |
| auto seed_store = std::make_unique<variations::VariationsSeedStore>( |
| local_state_.get(), /*initial_seed=*/GetAndClearJavaSeed(), |
| /*on_initial_seed_stored=*/base::DoNothing()); |
| variations_field_trial_creator_ = |
| std::make_unique<variations::VariationsFieldTrialCreator>( |
| local_state_.get(), client_.get(), std::move(seed_store), |
| ui_string_overrider); |
| variations_field_trial_creator_->OverrideVariationsPlatform( |
| variations::Study::PLATFORM_ANDROID_WEBVIEW); |
| |
| // Unused by WebView, but required by |
| // VariationsFieldTrialCreator::SetupFieldTrials(). |
| // TODO(isherman): We might want a more genuine SafeSeedManager: |
| // https://crbug.com/801771 |
| std::set<std::string> unforceable_field_trials; |
| variations::SafeSeedManager ignored_safe_seed_manager(true, |
| local_state_.get()); |
| |
| // Populate FieldTrialList. Since low_entropy_provider is null, it will fall |
| // back to the provider we previously gave to FieldTrialList, which is a low |
| // entropy provider. We only want one low entropy provider, because multiple |
| // CachingPermutedEntropyProvider objects would all try to cache their values |
| // in the same pref store, overwriting each other's. |
| variations_field_trial_creator_->SetupFieldTrials( |
| cc::switches::kEnableGpuBenchmarking, switches::kEnableFeatures, |
| switches::kDisableFeatures, unforceable_field_trials, |
| std::vector<std::string>(), /*low_entropy_provider=*/nullptr, |
| std::make_unique<base::FeatureList>(), aw_field_trials_.get(), |
| &ignored_safe_seed_manager); |
| } |
| |
| void AwFeatureListCreator::CreateFeatureListAndFieldTrials() { |
| browser_policy_connector_ = std::make_unique<AwBrowserPolicyConnector>(); |
| local_state_ = CreatePrefService(browser_policy_connector_.get()); |
| AwMetricsServiceClient::GetInstance()->Initialize(local_state_.get()); |
| SetUpFieldTrials(); |
| } |
| |
| } // namespace android_webview |