Index: chrome/browser/profile_resetter/automatic_profile_resetter.cc |
diff --git a/chrome/browser/profile_resetter/automatic_profile_resetter.cc b/chrome/browser/profile_resetter/automatic_profile_resetter.cc |
deleted file mode 100644 |
index 51ea44a6a4ddccedab0bdc58f4467cd8f341d1a7..0000000000000000000000000000000000000000 |
--- a/chrome/browser/profile_resetter/automatic_profile_resetter.cc |
+++ /dev/null |
@@ -1,763 +0,0 @@ |
-// Copyright 2013 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 "chrome/browser/profile_resetter/automatic_profile_resetter.h" |
- |
-#include "base/bind.h" |
-#include "base/bind_helpers.h" |
-#include "base/logging.h" |
-#include "base/memory/ref_counted.h" |
-#include "base/metrics/field_trial.h" |
-#include "base/metrics/histogram.h" |
-#include "base/metrics/sparse_histogram.h" |
-#include "base/prefs/pref_service.h" |
-#include "base/strings/string_number_conversions.h" |
-#include "base/strings/string_util.h" |
-#include "base/task_runner.h" |
-#include "base/task_runner_util.h" |
-#include "base/threading/sequenced_worker_pool.h" |
-#include "base/time/time.h" |
-#include "base/timer/elapsed_timer.h" |
-#include "base/values.h" |
-#include "chrome/browser/browser_process.h" |
-#include "chrome/browser/profile_resetter/automatic_profile_resetter_delegate.h" |
-#include "chrome/browser/profile_resetter/jtl_interpreter.h" |
-#include "chrome/browser/profiles/profile.h" |
-#include "chrome/browser/search_engines/template_url_service_factory.h" |
-#include "components/search_engines/template_url_service.h" |
-#include "components/variations/variations_associated_data.h" |
-#include "content/public/browser/browser_thread.h" |
-#include "grit/browser_resources.h" |
-#include "ui/base/resource/resource_bundle.h" |
- |
- |
-// Helpers ------------------------------------------------------------------- |
- |
-namespace { |
- |
-// Name constants for the field trial behind which we enable this feature. |
-const char kAutomaticProfileResetStudyName[] = "AutomaticProfileReset"; |
-const char kAutomaticProfileResetStudyDryRunGroupName[] = "DryRun"; |
-const char kAutomaticProfileResetStudyEnabledGroupName[] = "Enabled"; |
-#if defined(GOOGLE_CHROME_BUILD) |
-const char kAutomaticProfileResetStudyProgramParameterName[] = "program"; |
-const char kAutomaticProfileResetStudyHashSeedParameterName[] = "hash_seed"; |
-#endif |
- |
-// How long to wait after start-up before unleashing the evaluation flow. |
-const int64 kEvaluationFlowDelayInSeconds = 55; |
- |
-// Keys used in the input dictionary of the program. |
-const char kDefaultSearchProviderKey[] = "default_search_provider"; |
-const char kDefaultSearchProviderIsUserControlledKey[] = |
- "default_search_provider_iuc"; |
-const char kLoadedModuleDigestsKey[] = "loaded_modules"; |
-const char kLocalStateKey[] = "local_state"; |
-const char kLocalStateIsUserControlledKey[] = "local_state_iuc"; |
-const char kSearchProvidersKey[] = "search_providers"; |
-const char kUserPreferencesKey[] = "preferences"; |
-const char kUserPreferencesIsUserControlledKey[] = "preferences_iuc"; |
- |
-// Keys used in the output dictionary of the program. |
-const char kCombinedStatusMaskKeyPrefix[] = "combined_status_mask_bit"; |
-const char kHadPromptedAlreadyKey[] = "had_prompted_already"; |
-const char kShouldPromptKey[] = "should_prompt"; |
-const char kSatisfiedCriteriaMaskKeyPrefix[] = "satisfied_criteria_mask_bit"; |
- |
-// Keys used in both the input and output dictionary of the program. |
-const char kMementoValueInFileKey[] = "memento_value_in_file"; |
-const char kMementoValueInLocalStateKey[] = "memento_value_in_local_state"; |
-const char kMementoValueInPrefsKey[] = "memento_value_in_prefs"; |
- |
-// Number of bits, and maximum value (exclusive) for the mask whose bits |
-// indicate which of reset criteria were satisfied. |
-const size_t kSatisfiedCriteriaMaskNumberOfBits = 5u; |
-const uint32 kSatisfiedCriteriaMaskMaximumValue = |
- (1u << kSatisfiedCriteriaMaskNumberOfBits); |
- |
-// Number of bits, and maximum value (exclusive) for the mask whose bits |
-// indicate if any of reset criteria were satisfied, and which of the mementos |
-// were already present. |
-const size_t kCombinedStatusMaskNumberOfBits = 4u; |
-const uint32 kCombinedStatusMaskMaximumValue = |
- (1u << kCombinedStatusMaskNumberOfBits); |
- |
-// Returns whether or not a dry-run shall be performed. |
-bool ShouldPerformDryRun() { |
- return StartsWithASCII( |
- base::FieldTrialList::FindFullName(kAutomaticProfileResetStudyName), |
- kAutomaticProfileResetStudyDryRunGroupName, true); |
-} |
- |
-// Returns whether or not a live-run shall be performed. |
-bool ShouldPerformLiveRun() { |
- return StartsWithASCII( |
- base::FieldTrialList::FindFullName(kAutomaticProfileResetStudyName), |
- kAutomaticProfileResetStudyEnabledGroupName, true); |
-} |
- |
-// If the currently active experiment group prescribes a |program| and |
-// |hash_seed| to use instead of the baked-in ones, retrieves those and returns |
-// true. Otherwise, returns false. |
-bool GetProgramAndHashSeedOverridesFromExperiment(std::string* program, |
- std::string* hash_seed) { |
- DCHECK(program); |
- DCHECK(hash_seed); |
-#if defined(GOOGLE_CHROME_BUILD) |
- std::map<std::string, std::string> params; |
- variations::GetVariationParams(kAutomaticProfileResetStudyName, ¶ms); |
- if (params.count(kAutomaticProfileResetStudyProgramParameterName) && |
- params.count(kAutomaticProfileResetStudyHashSeedParameterName)) { |
- program->swap(params[kAutomaticProfileResetStudyProgramParameterName]); |
- hash_seed->swap(params[kAutomaticProfileResetStudyHashSeedParameterName]); |
- return true; |
- } |
-#endif |
- return false; |
-} |
- |
-// Takes |pref_name_to_value_map|, which shall be a deep-copy of all preferences |
-// in |source| without path expansion; and (1.) creates a sub-tree from it named |
-// |value_tree_key| in |target_dictionary| with path expansion, and (2.) also |
-// creates an isomorphic sub-tree under the key |is_user_controlled_tree_key| |
-// that contains only Boolean values indicating whether or not the corresponding |
-// preference is coming from the 'user' PrefStore. |
-void BuildSubTreesFromPreferences( |
- scoped_ptr<base::DictionaryValue> pref_name_to_value_map, |
- const PrefService* source, |
- const char* value_tree_key, |
- const char* is_user_controlled_tree_key, |
- base::DictionaryValue* target_dictionary) { |
- std::vector<std::string> pref_names; |
- pref_names.reserve(pref_name_to_value_map->size()); |
- for (base::DictionaryValue::Iterator it(*pref_name_to_value_map); |
- !it.IsAtEnd(); it.Advance()) |
- pref_names.push_back(it.key()); |
- |
- base::DictionaryValue* value_tree = new base::DictionaryValue; |
- base::DictionaryValue* is_user_controlled_tree = new base::DictionaryValue; |
- for (std::vector<std::string>::const_iterator it = pref_names.begin(); |
- it != pref_names.end(); ++it) { |
- scoped_ptr<base::Value> pref_value_owned; |
- if (pref_name_to_value_map->RemoveWithoutPathExpansion(*it, |
- &pref_value_owned)) { |
- value_tree->Set(*it, pref_value_owned.release()); |
- const PrefService::Preference* pref = source->FindPreference(it->c_str()); |
- is_user_controlled_tree->Set( |
- *it, new base::FundamentalValue(pref->IsUserControlled())); |
- } |
- } |
- target_dictionary->Set(value_tree_key, value_tree); |
- target_dictionary->Set(is_user_controlled_tree_key, is_user_controlled_tree); |
-} |
- |
-} // namespace |
- |
- |
-// AutomaticProfileResetter::InputBuilder ------------------------------------ |
- |
-// Collects all the information that is required by the evaluator program to |
-// assess whether or not the conditions for showing the reset prompt are met. |
-// |
-// This necessitates a lot of work that has to be performed on the UI thread, |
-// such as: accessing the Preferences, Local State, and TemplateURLService. |
-// In order to keep the browser responsive, the UI thread shall not be blocked |
-// for long consecutive periods of time. Unfortunately, we cannot reduce the |
-// total amount of work. Instead, what this class does is to split the work into |
-// shorter tasks that are posted one-at-a-time to the UI thread in a serial |
-// fashion, so as to give a chance to run other tasks that have accumulated in |
-// the meantime. |
-class AutomaticProfileResetter::InputBuilder |
- : public base::SupportsWeakPtr<InputBuilder> { |
- public: |
- typedef base::Callback<void(scoped_ptr<base::DictionaryValue>)> |
- ProgramInputCallback; |
- |
- // The dependencies must have been initialized through |delegate|, i.e. the |
- // RequestCallback[...] methods must have already fired before calling this. |
- InputBuilder(Profile* profile, AutomaticProfileResetterDelegate* delegate) |
- : profile_(profile), |
- delegate_(delegate), |
- memento_in_prefs_(profile_), |
- memento_in_local_state_(profile_), |
- memento_in_file_(profile_) {} |
- ~InputBuilder() {} |
- |
- // Assembles the data required by the evaluator program into a dictionary |
- // format, and posts it back to the UI thread with |callback| once ready. In |
- // order not to block the UI thread for long consecutive periods of time, the |
- // work is divided into smaller tasks, see class comment above for details. |
- // It is safe to destroy |this| immediately from within the |callback|. |
- void BuildEvaluatorProgramInput(const ProgramInputCallback& callback) { |
- DCHECK(!data_); |
- DCHECK(!callback.is_null()); |
- data_.reset(new base::DictionaryValue); |
- callback_ = callback; |
- |
- AddAsyncTask(base::Bind(&InputBuilder::IncludeMementoValues, AsWeakPtr())); |
- AddTask(base::Bind(&InputBuilder::IncludeUserPreferences, AsWeakPtr())); |
- AddTask(base::Bind(&InputBuilder::IncludeLocalState, AsWeakPtr())); |
- AddTask(base::Bind(&InputBuilder::IncludeSearchEngines, AsWeakPtr())); |
- AddTask(base::Bind(&InputBuilder::IncludeLoadedModules, AsWeakPtr())); |
- |
- // Each task will post the next one. Just trigger the chain reaction. |
- PostNextTask(); |
- } |
- |
- private: |
- // Asynchronous task that includes memento values (or empty strings in case |
- // mementos are not there). |
- void IncludeMementoValues() { |
- data_->SetString(kMementoValueInPrefsKey, memento_in_prefs_.ReadValue()); |
- data_->SetString(kMementoValueInLocalStateKey, |
- memento_in_local_state_.ReadValue()); |
- memento_in_file_.ReadValue(base::Bind( |
- &InputBuilder::IncludeFileBasedMementoCallback, AsWeakPtr())); |
- } |
- |
- // Called back by |memento_in_file_| once the |memento_value| has been read. |
- void IncludeFileBasedMementoCallback(const std::string& memento_value) { |
- DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
- data_->SetString(kMementoValueInFileKey, memento_value); |
- // As an asynchronous task, we need to take care of posting the next task. |
- PostNextTask(); |
- } |
- |
- // Task that includes all user (i.e. profile-specific) preferences, along with |
- // information about whether the value is coming from the 'user' PrefStore. |
- // This is the most expensive operation, so it is itself split into two parts. |
- void IncludeUserPreferences() { |
- PrefService* prefs = profile_->GetPrefs(); |
- DCHECK(prefs); |
- scoped_ptr<base::DictionaryValue> pref_name_to_value_map( |
- prefs->GetPreferenceValuesWithoutPathExpansion()); |
- AddTask(base::Bind(&InputBuilder::IncludeUserPreferencesPartTwo, |
- AsWeakPtr(), |
- base::Passed(&pref_name_to_value_map))); |
- } |
- |
- // Second part to above. |
- void IncludeUserPreferencesPartTwo( |
- scoped_ptr<base::DictionaryValue> pref_name_to_value_map) { |
- PrefService* prefs = profile_->GetPrefs(); |
- DCHECK(prefs); |
- BuildSubTreesFromPreferences( |
- pref_name_to_value_map.Pass(), |
- prefs, |
- kUserPreferencesKey, |
- kUserPreferencesIsUserControlledKey, |
- data_.get()); |
- } |
- |
- // Task that includes all local state (i.e. shared) preferences, along with |
- // information about whether the value is coming from the 'user' PrefStore. |
- void IncludeLocalState() { |
- PrefService* local_state = g_browser_process->local_state(); |
- DCHECK(local_state); |
- scoped_ptr<base::DictionaryValue> pref_name_to_value_map( |
- local_state->GetPreferenceValuesWithoutPathExpansion()); |
- BuildSubTreesFromPreferences( |
- pref_name_to_value_map.Pass(), |
- local_state, |
- kLocalStateKey, |
- kLocalStateIsUserControlledKey, |
- data_.get()); |
- } |
- |
- // Task that includes all information related to search engines. |
- void IncludeSearchEngines() { |
- scoped_ptr<base::DictionaryValue> default_search_provider_details( |
- delegate_->GetDefaultSearchProviderDetails()); |
- data_->Set(kDefaultSearchProviderKey, |
- default_search_provider_details.release()); |
- |
- scoped_ptr<base::ListValue> search_providers_details( |
- delegate_->GetPrepopulatedSearchProvidersDetails()); |
- data_->Set(kSearchProvidersKey, search_providers_details.release()); |
- |
- data_->SetBoolean(kDefaultSearchProviderIsUserControlledKey, |
- !delegate_->IsDefaultSearchProviderManaged()); |
- } |
- |
- // Task that includes information about loaded modules. |
- void IncludeLoadedModules() { |
- scoped_ptr<base::ListValue> loaded_module_digests( |
- delegate_->GetLoadedModuleNameDigests()); |
- data_->Set(kLoadedModuleDigestsKey, loaded_module_digests.release()); |
- } |
- |
- // ------------------------------------------------------------------------- |
- |
- // Adds a |task| that can do as much asynchronous processing as it wants, but |
- // will need to finally call PostNextTask() on the UI thread when done. |
- void AddAsyncTask(const base::Closure& task) { |
- task_queue_.push(task); |
- } |
- |
- // Convenience wrapper for synchronous tasks. |
- void SynchronousTaskWrapper(const base::Closure& task) { |
- base::ElapsedTimer timer; |
- task.Run(); |
- UMA_HISTOGRAM_CUSTOM_TIMES( |
- "AutomaticProfileReset.InputBuilder.TaskDuration", |
- timer.Elapsed(), |
- base::TimeDelta::FromMilliseconds(1), |
- base::TimeDelta::FromSeconds(2), |
- 50); |
- PostNextTask(); |
- } |
- |
- // Adds a task that needs to finish synchronously. In exchange, PostNextTask() |
- // is called automatically when the |task| returns, and execution time is |
- // measured. |
- void AddTask(const base::Closure& task) { |
- task_queue_.push( |
- base::Bind(&InputBuilder::SynchronousTaskWrapper, AsWeakPtr(), task)); |
- } |
- |
- // Posts the next task from the |task_queue_|, unless it is exhausted, in |
- // which case it posts |callback_| to return with the results. |
- void PostNextTask() { |
- base::Closure next_task; |
- if (task_queue_.empty()) { |
- next_task = base::Bind(callback_, base::Passed(&data_)); |
- } else { |
- next_task = task_queue_.front(); |
- task_queue_.pop(); |
- } |
- content::BrowserThread::PostTask( |
- content::BrowserThread::UI, FROM_HERE, next_task); |
- } |
- |
- Profile* profile_; |
- AutomaticProfileResetterDelegate* delegate_; |
- ProgramInputCallback callback_; |
- |
- PreferenceHostedPromptMemento memento_in_prefs_; |
- LocalStateHostedPromptMemento memento_in_local_state_; |
- FileHostedPromptMemento memento_in_file_; |
- |
- scoped_ptr<base::DictionaryValue> data_; |
- std::queue<base::Closure> task_queue_; |
- |
- DISALLOW_COPY_AND_ASSIGN(InputBuilder); |
-}; |
- |
- |
-// AutomaticProfileResetter::EvaluationResults ------------------------------- |
- |
-// Encapsulates the output values extracted from the evaluator program. |
-struct AutomaticProfileResetter::EvaluationResults { |
- EvaluationResults() |
- : should_prompt(false), |
- had_prompted_already(false), |
- satisfied_criteria_mask(0), |
- combined_status_mask(0) {} |
- |
- std::string memento_value_in_prefs; |
- std::string memento_value_in_local_state; |
- std::string memento_value_in_file; |
- |
- bool should_prompt; |
- bool had_prompted_already; |
- uint32 satisfied_criteria_mask; |
- uint32 combined_status_mask; |
-}; |
- |
- |
-// AutomaticProfileResetter -------------------------------------------------- |
- |
-AutomaticProfileResetter::AutomaticProfileResetter(Profile* profile) |
- : profile_(profile), |
- state_(STATE_UNINITIALIZED), |
- enumeration_of_loaded_modules_ready_(false), |
- template_url_service_ready_(false), |
- has_already_dismissed_prompt_(false), |
- should_show_reset_banner_(false), |
- weak_ptr_factory_(this) { |
- DCHECK(profile_); |
-} |
- |
-AutomaticProfileResetter::~AutomaticProfileResetter() {} |
- |
-void AutomaticProfileResetter::Initialize() { |
- DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
- DCHECK_EQ(state_, STATE_UNINITIALIZED); |
- |
- if (!ShouldPerformDryRun() && !ShouldPerformLiveRun()) { |
- state_ = STATE_DISABLED; |
- return; |
- } |
- |
- if (!GetProgramAndHashSeedOverridesFromExperiment(&program_, &hash_seed_)) { |
- ui::ResourceBundle& resources(ui::ResourceBundle::GetSharedInstance()); |
- if (ShouldPerformLiveRun()) { |
- program_ = resources.GetRawDataResource( |
- IDR_AUTOMATIC_PROFILE_RESET_RULES).as_string(); |
- hash_seed_ = resources.GetRawDataResource( |
- IDR_AUTOMATIC_PROFILE_RESET_HASH_SEED).as_string(); |
- } else { // ShouldPerformDryRun() |
- program_ = resources.GetRawDataResource( |
- IDR_AUTOMATIC_PROFILE_RESET_RULES_DRY).as_string(); |
- hash_seed_ = resources.GetRawDataResource( |
- IDR_AUTOMATIC_PROFILE_RESET_HASH_SEED_DRY).as_string(); |
- } |
- } |
- |
- delegate_.reset(new AutomaticProfileResetterDelegateImpl( |
- profile_, ProfileResetter::ALL)); |
- task_runner_for_waiting_ = |
- content::BrowserThread::GetMessageLoopProxyForThread( |
- content::BrowserThread::UI); |
- |
- state_ = STATE_INITIALIZED; |
-} |
- |
-void AutomaticProfileResetter::Activate() { |
- DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
- DCHECK(state_ == STATE_INITIALIZED || state_ == STATE_DISABLED); |
- |
- if (state_ == STATE_INITIALIZED) { |
- if (!program_.empty()) { |
- // Some steps in the flow (e.g. loaded modules, file-based memento) are |
- // IO-intensive, so defer execution until some time later. |
- task_runner_for_waiting_->PostDelayedTask( |
- FROM_HERE, |
- base::Bind(&AutomaticProfileResetter::PrepareEvaluationFlow, |
- weak_ptr_factory_.GetWeakPtr()), |
- base::TimeDelta::FromSeconds(kEvaluationFlowDelayInSeconds)); |
- } else { |
- // Terminate early if there is no program included (nor set by tests). |
- state_ = STATE_DISABLED; |
- } |
- } |
-} |
- |
-void AutomaticProfileResetter::TriggerProfileReset(bool send_feedback) { |
- DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
- DCHECK_EQ(state_, STATE_HAS_SHOWN_BUBBLE); |
- |
- state_ = STATE_PERFORMING_RESET; |
- should_show_reset_banner_ = false; |
- |
- ReportPromptResult(PROMPT_ACTION_RESET); |
- delegate_->TriggerProfileSettingsReset( |
- send_feedback, |
- base::Bind(&AutomaticProfileResetter::OnProfileSettingsResetCompleted, |
- weak_ptr_factory_.GetWeakPtr())); |
-} |
- |
-void AutomaticProfileResetter::SkipProfileReset() { |
- DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
- DCHECK_EQ(state_, STATE_HAS_SHOWN_BUBBLE); |
- |
- should_show_reset_banner_ = false; |
- |
- ReportPromptResult(PROMPT_ACTION_NO_RESET); |
- delegate_->DismissPrompt(); |
- FinishResetPromptFlow(); |
-} |
- |
-bool AutomaticProfileResetter::IsResetPromptFlowActive() const { |
- return state_ == STATE_HAS_TRIGGERED_PROMPT || |
- state_ == STATE_HAS_SHOWN_BUBBLE; |
-} |
- |
-bool AutomaticProfileResetter::ShouldShowResetBanner() const { |
- DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
- return should_show_reset_banner_ && ShouldPerformLiveRun(); |
-} |
- |
-void AutomaticProfileResetter::NotifyDidShowResetBubble() { |
- DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
- DCHECK_EQ(state_, STATE_HAS_TRIGGERED_PROMPT); |
- |
- state_ = STATE_HAS_SHOWN_BUBBLE; |
- |
- PersistMementos(); |
- ReportPromptResult(PROMPT_SHOWN_BUBBLE); |
-} |
- |
-void AutomaticProfileResetter::NotifyDidOpenWebUIResetDialog() { |
- DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
- |
- // This notification is invoked unconditionally by the WebUI, only care about |
- // it when the prompt flow is currently active (and not yet resetting). |
- if (state_ == STATE_HAS_TRIGGERED_PROMPT || |
- state_ == STATE_HAS_SHOWN_BUBBLE) { |
- has_already_dismissed_prompt_ = true; |
- delegate_->DismissPrompt(); |
- } |
-} |
- |
-void AutomaticProfileResetter::NotifyDidCloseWebUIResetDialog( |
- bool performed_reset) { |
- DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
- |
- // This notification is invoked unconditionally by the WebUI, only care about |
- // it when the prompt flow is currently active (and not yet resetting). |
- if (state_ == STATE_HAS_TRIGGERED_PROMPT || |
- state_ == STATE_HAS_SHOWN_BUBBLE) { |
- if (!has_already_dismissed_prompt_) |
- delegate_->DismissPrompt(); |
- if (state_ == STATE_HAS_TRIGGERED_PROMPT) { |
- PersistMementos(); |
- ReportPromptResult(performed_reset ? |
- PROMPT_NOT_SHOWN_BUBBLE_BUT_HAD_WEBUI_RESET : |
- PROMPT_NOT_SHOWN_BUBBLE_BUT_HAD_WEBUI_NO_RESET); |
- } else { // if (state_ == STATE_HAS_SHOWN_PROMPT) |
- ReportPromptResult(performed_reset ? |
- PROMPT_FOLLOWED_BY_WEBUI_RESET : |
- PROMPT_FOLLOWED_BY_WEBUI_NO_RESET); |
- } |
- FinishResetPromptFlow(); |
- } |
-} |
- |
-void AutomaticProfileResetter::NotifyDidCloseWebUIResetBanner() { |
- DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
- should_show_reset_banner_ = false; |
-} |
- |
-void AutomaticProfileResetter::SetProgramForTesting( |
- const std::string& program) { |
- program_ = program; |
-} |
- |
-void AutomaticProfileResetter::SetHashSeedForTesting( |
- const std::string& hash_key) { |
- hash_seed_ = hash_key; |
-} |
- |
-void AutomaticProfileResetter::SetDelegateForTesting( |
- scoped_ptr<AutomaticProfileResetterDelegate> delegate) { |
- delegate_ = delegate.Pass(); |
-} |
- |
-void AutomaticProfileResetter::SetTaskRunnerForWaitingForTesting( |
- const scoped_refptr<base::TaskRunner>& task_runner) { |
- task_runner_for_waiting_ = task_runner; |
-} |
- |
-void AutomaticProfileResetter::Shutdown() { |
- DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
- |
- // We better not do anything substantial at this point. The metrics service |
- // has already been shut down; and local state has already been commited to |
- // file (in the regular fashion) for the last time. |
- |
- state_ = STATE_DISABLED; |
- |
- weak_ptr_factory_.InvalidateWeakPtrs(); |
- delegate_.reset(); |
-} |
- |
-void AutomaticProfileResetter::PrepareEvaluationFlow() { |
- DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
- DCHECK_EQ(state_, STATE_INITIALIZED); |
- |
- state_ = STATE_WAITING_ON_DEPENDENCIES; |
- |
- delegate_->RequestCallbackWhenTemplateURLServiceIsLoaded( |
- base::Bind(&AutomaticProfileResetter::OnTemplateURLServiceIsLoaded, |
- weak_ptr_factory_.GetWeakPtr())); |
- delegate_->RequestCallbackWhenLoadedModulesAreEnumerated( |
- base::Bind(&AutomaticProfileResetter::OnLoadedModulesAreEnumerated, |
- weak_ptr_factory_.GetWeakPtr())); |
- delegate_->LoadTemplateURLServiceIfNeeded(); |
- delegate_->EnumerateLoadedModulesIfNeeded(); |
-} |
- |
-void AutomaticProfileResetter::OnTemplateURLServiceIsLoaded() { |
- template_url_service_ready_ = true; |
- OnDependencyIsReady(); |
-} |
- |
-void AutomaticProfileResetter::OnLoadedModulesAreEnumerated() { |
- enumeration_of_loaded_modules_ready_ = true; |
- OnDependencyIsReady(); |
-} |
- |
-void AutomaticProfileResetter::OnDependencyIsReady() { |
- DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
- DCHECK_EQ(state_, STATE_WAITING_ON_DEPENDENCIES); |
- |
- if (template_url_service_ready_ && enumeration_of_loaded_modules_ready_) { |
- state_ = STATE_READY; |
- content::BrowserThread::PostTask( |
- content::BrowserThread::UI, |
- FROM_HERE, |
- base::Bind(&AutomaticProfileResetter::BeginEvaluationFlow, |
- weak_ptr_factory_.GetWeakPtr())); |
- } |
-} |
- |
-void AutomaticProfileResetter::BeginEvaluationFlow() { |
- DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
- DCHECK_EQ(state_, STATE_READY); |
- DCHECK(!program_.empty()); |
- DCHECK(!input_builder_); |
- |
- state_ = STATE_EVALUATING_CONDITIONS; |
- |
- input_builder_.reset(new InputBuilder(profile_, delegate_.get())); |
- input_builder_->BuildEvaluatorProgramInput( |
- base::Bind(&AutomaticProfileResetter::ContinueWithEvaluationFlow, |
- weak_ptr_factory_.GetWeakPtr())); |
-} |
- |
-void AutomaticProfileResetter::ContinueWithEvaluationFlow( |
- scoped_ptr<base::DictionaryValue> program_input) { |
- DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
- DCHECK_EQ(state_, STATE_EVALUATING_CONDITIONS); |
- |
- input_builder_.reset(); |
- |
- base::SequencedWorkerPool* blocking_pool = |
- content::BrowserThread::GetBlockingPool(); |
- scoped_refptr<base::TaskRunner> task_runner = |
- blocking_pool->GetTaskRunnerWithShutdownBehavior( |
- base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); |
- |
- base::PostTaskAndReplyWithResult( |
- task_runner.get(), |
- FROM_HERE, |
- base::Bind(&EvaluateConditionsOnWorkerPoolThread, |
- hash_seed_, |
- program_, |
- base::Passed(&program_input)), |
- base::Bind(&AutomaticProfileResetter::FinishEvaluationFlow, |
- weak_ptr_factory_.GetWeakPtr())); |
-} |
- |
-// static |
-scoped_ptr<AutomaticProfileResetter::EvaluationResults> |
- AutomaticProfileResetter::EvaluateConditionsOnWorkerPoolThread( |
- const std::string& hash_seed, |
- const std::string& program, |
- scoped_ptr<base::DictionaryValue> program_input) { |
- JtlInterpreter interpreter(hash_seed, program, program_input.get()); |
- interpreter.Execute(); |
- UMA_HISTOGRAM_ENUMERATION("AutomaticProfileReset.InterpreterResult", |
- interpreter.result(), |
- JtlInterpreter::RESULT_MAX); |
- UMA_HISTOGRAM_SPARSE_SLOWLY("AutomaticProfileReset.ProgramChecksum", |
- interpreter.CalculateProgramChecksum()); |
- |
- // In each case below, the respective field in result originally contains the |
- // default, so if the getter fails, we still have the correct value there. |
- scoped_ptr<EvaluationResults> results(new EvaluationResults); |
- interpreter.GetOutputBoolean(kShouldPromptKey, &results->should_prompt); |
- interpreter.GetOutputBoolean(kHadPromptedAlreadyKey, |
- &results->had_prompted_already); |
- interpreter.GetOutputString(kMementoValueInPrefsKey, |
- &results->memento_value_in_prefs); |
- interpreter.GetOutputString(kMementoValueInLocalStateKey, |
- &results->memento_value_in_local_state); |
- interpreter.GetOutputString(kMementoValueInFileKey, |
- &results->memento_value_in_file); |
- for (size_t i = 0; i < kCombinedStatusMaskNumberOfBits; ++i) { |
- bool flag = false; |
- std::string mask_i_th_bit_key = |
- kCombinedStatusMaskKeyPrefix + base::IntToString(i + 1); |
- if (interpreter.GetOutputBoolean(mask_i_th_bit_key, &flag) && flag) |
- results->combined_status_mask |= (1 << i); |
- } |
- for (size_t i = 0; i < kSatisfiedCriteriaMaskNumberOfBits; ++i) { |
- bool flag = false; |
- std::string mask_i_th_bit_key = |
- kSatisfiedCriteriaMaskKeyPrefix + base::IntToString(i + 1); |
- if (interpreter.GetOutputBoolean(mask_i_th_bit_key, &flag) && flag) |
- results->satisfied_criteria_mask |= (1 << i); |
- } |
- return results.Pass(); |
-} |
- |
-void AutomaticProfileResetter::ReportStatistics(uint32 satisfied_criteria_mask, |
- uint32 combined_status_mask) { |
- UMA_HISTOGRAM_ENUMERATION("AutomaticProfileReset.SatisfiedCriteriaMask", |
- satisfied_criteria_mask, |
- kSatisfiedCriteriaMaskMaximumValue); |
- UMA_HISTOGRAM_ENUMERATION("AutomaticProfileReset.CombinedStatusMask", |
- combined_status_mask, |
- kCombinedStatusMaskMaximumValue); |
-} |
- |
-void AutomaticProfileResetter::FinishEvaluationFlow( |
- scoped_ptr<EvaluationResults> results) { |
- DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
- DCHECK_EQ(state_, STATE_EVALUATING_CONDITIONS); |
- |
- ReportStatistics(results->satisfied_criteria_mask, |
- results->combined_status_mask); |
- |
- if (results->should_prompt) |
- should_show_reset_banner_ = true; |
- |
- if (results->should_prompt && !results->had_prompted_already) { |
- evaluation_results_ = results.Pass(); |
- BeginResetPromptFlow(); |
- } else { |
- state_ = STATE_DONE; |
- } |
-} |
- |
-void AutomaticProfileResetter::BeginResetPromptFlow() { |
- DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
- DCHECK_EQ(state_, STATE_EVALUATING_CONDITIONS); |
- |
- state_ = STATE_HAS_TRIGGERED_PROMPT; |
- |
- if (ShouldPerformLiveRun() && delegate_->TriggerPrompt()) { |
- // Start fetching the brandcoded default settings speculatively in the |
- // background, so as to reduce waiting time if the user chooses to go |
- // through with the reset. |
- delegate_->FetchBrandcodedDefaultSettingsIfNeeded(); |
- } else { |
- PersistMementos(); |
- ReportPromptResult(PROMPT_NOT_TRIGGERED); |
- FinishResetPromptFlow(); |
- } |
-} |
- |
-void AutomaticProfileResetter::OnProfileSettingsResetCompleted() { |
- DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
- DCHECK_EQ(state_, STATE_PERFORMING_RESET); |
- |
- delegate_->DismissPrompt(); |
- FinishResetPromptFlow(); |
-} |
- |
-void AutomaticProfileResetter::ReportPromptResult(PromptResult result) { |
- UMA_HISTOGRAM_ENUMERATION( |
- "AutomaticProfileReset.PromptResult", result, PROMPT_RESULT_MAX); |
-} |
- |
-void AutomaticProfileResetter::PersistMementos() { |
- DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
- DCHECK(state_ == STATE_HAS_TRIGGERED_PROMPT || |
- state_ == STATE_HAS_SHOWN_BUBBLE); |
- DCHECK(evaluation_results_); |
- |
- PreferenceHostedPromptMemento memento_in_prefs(profile_); |
- LocalStateHostedPromptMemento memento_in_local_state(profile_); |
- FileHostedPromptMemento memento_in_file(profile_); |
- |
- memento_in_prefs.StoreValue(evaluation_results_->memento_value_in_prefs); |
- memento_in_local_state.StoreValue( |
- evaluation_results_->memento_value_in_local_state); |
- memento_in_file.StoreValue(evaluation_results_->memento_value_in_file); |
- |
- evaluation_results_.reset(); |
-} |
- |
-void AutomaticProfileResetter::FinishResetPromptFlow() { |
- DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
- DCHECK(state_ == STATE_HAS_TRIGGERED_PROMPT || |
- state_ == STATE_HAS_SHOWN_BUBBLE || |
- state_ == STATE_PERFORMING_RESET); |
- DCHECK(!evaluation_results_); |
- |
- state_ = STATE_DONE; |
-} |