14e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 24e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 34e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// found in the LICENSE file. 44e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 54e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/profile_resetter/automatic_profile_resetter.h" 64e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 71e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/bind.h" 84e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/bind_helpers.h" 94e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/logging.h" 104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/memory/ref_counted.h" 114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/metrics/field_trial.h" 124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/metrics/histogram.h" 135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/metrics/sparse_histogram.h" 144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/prefs/pref_service.h" 151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/strings/string_number_conversions.h" 16f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/strings/string_util.h" 174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/task_runner.h" 184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/task_runner_util.h" 194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/threading/sequenced_worker_pool.h" 201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/time/time.h" 21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/timer/elapsed_timer.h" 221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/values.h" 231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "chrome/browser/browser_process.h" 241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "chrome/browser/profile_resetter/automatic_profile_resetter_delegate.h" 254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/profile_resetter/jtl_interpreter.h" 264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/profiles/profile.h" 271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "chrome/browser/search_engines/template_url_service.h" 281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "chrome/browser/search_engines/template_url_service_factory.h" 29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "components/variations/variations_associated_data.h" 304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "content/public/browser/browser_thread.h" 314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "grit/browser_resources.h" 324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ui/base/resource/resource_bundle.h" 334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// Helpers ------------------------------------------------------------------- 361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)namespace { 384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Name constants for the field trial behind which we enable this feature. 404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const char kAutomaticProfileResetStudyName[] = "AutomaticProfileReset"; 414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const char kAutomaticProfileResetStudyDryRunGroupName[] = "DryRun"; 424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const char kAutomaticProfileResetStudyEnabledGroupName[] = "Enabled"; 43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if defined(GOOGLE_CHROME_BUILD) 44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)const char kAutomaticProfileResetStudyProgramParameterName[] = "program"; 45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)const char kAutomaticProfileResetStudyHashSeedParameterName[] = "hash_seed"; 46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif 474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// How long to wait after start-up before unleashing the evaluation flow. 491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)const int64 kEvaluationFlowDelayInSeconds = 55; 501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Keys used in the input dictionary of the program. 521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)const char kDefaultSearchProviderKey[] = "default_search_provider"; 531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)const char kDefaultSearchProviderIsUserControlledKey[] = 541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) "default_search_provider_iuc"; 551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)const char kLoadedModuleDigestsKey[] = "loaded_modules"; 561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)const char kLocalStateKey[] = "local_state"; 571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)const char kLocalStateIsUserControlledKey[] = "local_state_iuc"; 581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)const char kSearchProvidersKey[] = "search_providers"; 591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)const char kUserPreferencesKey[] = "preferences"; 601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)const char kUserPreferencesIsUserControlledKey[] = "preferences_iuc"; 614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Keys used in the output dictionary of the program. 63a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)const char kCombinedStatusMaskKeyPrefix[] = "combined_status_mask_bit"; 641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)const char kHadPromptedAlreadyKey[] = "had_prompted_already"; 65a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)const char kShouldPromptKey[] = "should_prompt"; 66a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)const char kSatisfiedCriteriaMaskKeyPrefix[] = "satisfied_criteria_mask_bit"; 674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Keys used in both the input and output dictionary of the program. 694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const char kMementoValueInFileKey[] = "memento_value_in_file"; 701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)const char kMementoValueInLocalStateKey[] = "memento_value_in_local_state"; 711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)const char kMementoValueInPrefsKey[] = "memento_value_in_prefs"; 724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// Number of bits, and maximum value (exclusive) for the mask whose bits 741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// indicate which of reset criteria were satisfied. 75a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)const size_t kSatisfiedCriteriaMaskNumberOfBits = 5u; 761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)const uint32 kSatisfiedCriteriaMaskMaximumValue = 771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) (1u << kSatisfiedCriteriaMaskNumberOfBits); 784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// Number of bits, and maximum value (exclusive) for the mask whose bits 801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// indicate if any of reset criteria were satisfied, and which of the mementos 811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// were already present. 821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)const size_t kCombinedStatusMaskNumberOfBits = 4u; 831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)const uint32 kCombinedStatusMaskMaximumValue = 841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) (1u << kCombinedStatusMaskNumberOfBits); 854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// Returns whether or not a dry-run shall be performed. 871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)bool ShouldPerformDryRun() { 88f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return StartsWithASCII( 89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::FieldTrialList::FindFullName(kAutomaticProfileResetStudyName), 90f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) kAutomaticProfileResetStudyDryRunGroupName, true); 911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// Returns whether or not a live-run shall be performed. 941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)bool ShouldPerformLiveRun() { 95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return StartsWithASCII( 96f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::FieldTrialList::FindFullName(kAutomaticProfileResetStudyName), 97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) kAutomaticProfileResetStudyEnabledGroupName, true); 98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 99f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// If the currently active experiment group prescribes a |program| and 101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// |hash_seed| to use instead of the baked-in ones, retrieves those and returns 102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// true. Otherwise, returns false. 103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool GetProgramAndHashSeedOverridesFromExperiment(std::string* program, 104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::string* hash_seed) { 105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(program); 106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(hash_seed); 107f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if defined(GOOGLE_CHROME_BUILD) 108f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::map<std::string, std::string> params; 109f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) chrome_variations::GetVariationParams(kAutomaticProfileResetStudyName, 110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ¶ms); 111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (params.count(kAutomaticProfileResetStudyProgramParameterName) && 112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) params.count(kAutomaticProfileResetStudyHashSeedParameterName)) { 113f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) program->swap(params[kAutomaticProfileResetStudyProgramParameterName]); 114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hash_seed->swap(params[kAutomaticProfileResetStudyHashSeedParameterName]); 115f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return true; 116f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 117f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif 118f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return false; 119f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 120f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 121f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Takes |pref_name_to_value_map|, which shall be a deep-copy of all preferences 122f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// in |source| without path expansion; and (1.) creates a sub-tree from it named 123f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// |value_tree_key| in |target_dictionary| with path expansion, and (2.) also 124f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// creates an isomorphic sub-tree under the key |is_user_controlled_tree_key| 125f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// that contains only Boolean values indicating whether or not the corresponding 126f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// preference is coming from the 'user' PrefStore. 127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void BuildSubTreesFromPreferences( 128f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<base::DictionaryValue> pref_name_to_value_map, 129f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const PrefService* source, 130f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const char* value_tree_key, 131f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const char* is_user_controlled_tree_key, 132f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::DictionaryValue* target_dictionary) { 1331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) std::vector<std::string> pref_names; 1341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) pref_names.reserve(pref_name_to_value_map->size()); 1351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) for (base::DictionaryValue::Iterator it(*pref_name_to_value_map); 1361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) !it.IsAtEnd(); it.Advance()) 1371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) pref_names.push_back(it.key()); 1381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) base::DictionaryValue* value_tree = new base::DictionaryValue; 1401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) base::DictionaryValue* is_user_controlled_tree = new base::DictionaryValue; 1411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) for (std::vector<std::string>::const_iterator it = pref_names.begin(); 1421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) it != pref_names.end(); ++it) { 1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<base::Value> pref_value_owned; 1441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (pref_name_to_value_map->RemoveWithoutPathExpansion(*it, 1451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) &pref_value_owned)) { 1461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) value_tree->Set(*it, pref_value_owned.release()); 1471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const PrefService::Preference* pref = source->FindPreference(it->c_str()); 1481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) is_user_controlled_tree->Set( 1491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) *it, new base::FundamentalValue(pref->IsUserControlled())); 1501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 1511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 1521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) target_dictionary->Set(value_tree_key, value_tree); 1531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) target_dictionary->Set(is_user_controlled_tree_key, is_user_controlled_tree); 1541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 1554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} // namespace 1574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 159f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// AutomaticProfileResetter::InputBuilder ------------------------------------ 160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 161f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Collects all the information that is required by the evaluator program to 162f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// assess whether or not the conditions for showing the reset prompt are met. 163f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// 164f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// This necessitates a lot of work that has to be performed on the UI thread, 165f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// such as: accessing the Preferences, Local State, and TemplateURLService. 166f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// In order to keep the browser responsive, the UI thread shall not be blocked 167f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// for long consecutive periods of time. Unfortunately, we cannot reduce the 168f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// total amount of work. Instead, what this class does is to split the work into 169f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// shorter tasks that are posted one-at-a-time to the UI thread in a serial 170f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// fashion, so as to give a chance to run other tasks that have accumulated in 171f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// the meantime. 172f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class AutomaticProfileResetter::InputBuilder 173f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) : public base::SupportsWeakPtr<InputBuilder> { 174f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) public: 175f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) typedef base::Callback<void(scoped_ptr<base::DictionaryValue>)> 176f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ProgramInputCallback; 177f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 178f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // The dependencies must have been initialized through |delegate|, i.e. the 179f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // RequestCallback[...] methods must have already fired before calling this. 180f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) InputBuilder(Profile* profile, AutomaticProfileResetterDelegate* delegate) 181f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) : profile_(profile), 182f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) delegate_(delegate), 183f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) memento_in_prefs_(profile_), 184f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) memento_in_local_state_(profile_), 185f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) memento_in_file_(profile_) {} 186f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ~InputBuilder() {} 187f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 188f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Assembles the data required by the evaluator program into a dictionary 189f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // format, and posts it back to the UI thread with |callback| once ready. In 190f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // order not to block the UI thread for long consecutive periods of time, the 191f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // work is divided into smaller tasks, see class comment above for details. 192f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // It is safe to destroy |this| immediately from within the |callback|. 193f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void BuildEvaluatorProgramInput(const ProgramInputCallback& callback) { 194f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(!data_); 195f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(!callback.is_null()); 196f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) data_.reset(new base::DictionaryValue); 197f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) callback_ = callback; 198f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 199f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) AddAsyncTask(base::Bind(&InputBuilder::IncludeMementoValues, AsWeakPtr())); 200f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) AddTask(base::Bind(&InputBuilder::IncludeUserPreferences, AsWeakPtr())); 201f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) AddTask(base::Bind(&InputBuilder::IncludeLocalState, AsWeakPtr())); 202f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) AddTask(base::Bind(&InputBuilder::IncludeSearchEngines, AsWeakPtr())); 203f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) AddTask(base::Bind(&InputBuilder::IncludeLoadedModules, AsWeakPtr())); 204f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 205f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Each task will post the next one. Just trigger the chain reaction. 206f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PostNextTask(); 207f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 208f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 209f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) private: 210f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Asynchronous task that includes memento values (or empty strings in case 211f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // mementos are not there). 212f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void IncludeMementoValues() { 213f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) data_->SetString(kMementoValueInPrefsKey, memento_in_prefs_.ReadValue()); 214f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) data_->SetString(kMementoValueInLocalStateKey, 215f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) memento_in_local_state_.ReadValue()); 216f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) memento_in_file_.ReadValue(base::Bind( 217f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) &InputBuilder::IncludeFileBasedMementoCallback, AsWeakPtr())); 218f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 219f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 220f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Called back by |memento_in_file_| once the |memento_value| has been read. 221f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void IncludeFileBasedMementoCallback(const std::string& memento_value) { 222f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 223f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) data_->SetString(kMementoValueInFileKey, memento_value); 224f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // As an asynchronous task, we need to take care of posting the next task. 225f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PostNextTask(); 226f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 227f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 228f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Task that includes all user (i.e. profile-specific) preferences, along with 229f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // information about whether the value is coming from the 'user' PrefStore. 230f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // This is the most expensive operation, so it is itself split into two parts. 231f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void IncludeUserPreferences() { 232f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PrefService* prefs = profile_->GetPrefs(); 233f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(prefs); 234f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<base::DictionaryValue> pref_name_to_value_map( 235f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) prefs->GetPreferenceValuesWithoutPathExpansion()); 236f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) AddTask(base::Bind(&InputBuilder::IncludeUserPreferencesPartTwo, 237f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) AsWeakPtr(), 238f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::Passed(&pref_name_to_value_map))); 239f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 240f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 241f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Second part to above. 242f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void IncludeUserPreferencesPartTwo( 243f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<base::DictionaryValue> pref_name_to_value_map) { 244f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PrefService* prefs = profile_->GetPrefs(); 245f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(prefs); 246f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) BuildSubTreesFromPreferences( 247f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) pref_name_to_value_map.Pass(), 248f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) prefs, 249f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) kUserPreferencesKey, 250f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) kUserPreferencesIsUserControlledKey, 251f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) data_.get()); 252f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 253f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 254f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Task that includes all local state (i.e. shared) preferences, along with 255f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // information about whether the value is coming from the 'user' PrefStore. 256f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void IncludeLocalState() { 257f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PrefService* local_state = g_browser_process->local_state(); 258f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(local_state); 259f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<base::DictionaryValue> pref_name_to_value_map( 260f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) local_state->GetPreferenceValuesWithoutPathExpansion()); 261f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) BuildSubTreesFromPreferences( 262f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) pref_name_to_value_map.Pass(), 263f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) local_state, 264f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) kLocalStateKey, 265f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) kLocalStateIsUserControlledKey, 266f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) data_.get()); 267f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 268f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 269f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Task that includes all information related to search engines. 270f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void IncludeSearchEngines() { 271f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<base::DictionaryValue> default_search_provider_details( 272f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) delegate_->GetDefaultSearchProviderDetails()); 273f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) data_->Set(kDefaultSearchProviderKey, 274f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) default_search_provider_details.release()); 275f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 276f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<base::ListValue> search_providers_details( 277f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) delegate_->GetPrepopulatedSearchProvidersDetails()); 278f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) data_->Set(kSearchProvidersKey, search_providers_details.release()); 279f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 280f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) data_->SetBoolean(kDefaultSearchProviderIsUserControlledKey, 281f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) !delegate_->IsDefaultSearchProviderManaged()); 282f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 283f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 284f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Task that includes information about loaded modules. 285f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void IncludeLoadedModules() { 286f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<base::ListValue> loaded_module_digests( 287f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) delegate_->GetLoadedModuleNameDigests()); 288f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) data_->Set(kLoadedModuleDigestsKey, loaded_module_digests.release()); 289f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 290f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 291f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // ------------------------------------------------------------------------- 292f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 293f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Adds a |task| that can do as much asynchronous processing as it wants, but 294f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // will need to finally call PostNextTask() on the UI thread when done. 295f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void AddAsyncTask(const base::Closure& task) { 296f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) task_queue_.push(task); 297f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 298f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 299f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Convenience wrapper for synchronous tasks. 300f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void SynchronousTaskWrapper(const base::Closure& task) { 301f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::ElapsedTimer timer; 302f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) task.Run(); 303f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) UMA_HISTOGRAM_CUSTOM_TIMES( 304f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) "AutomaticProfileReset.InputBuilder.TaskDuration", 305f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) timer.Elapsed(), 306f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::TimeDelta::FromMilliseconds(1), 307f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::TimeDelta::FromSeconds(2), 308f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 50); 309f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PostNextTask(); 310f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 311f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 312f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Adds a task that needs to finish synchronously. In exchange, PostNextTask() 313f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // is called automatically when the |task| returns, and execution time is 314f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // measured. 315f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void AddTask(const base::Closure& task) { 316f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) task_queue_.push( 317f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::Bind(&InputBuilder::SynchronousTaskWrapper, AsWeakPtr(), task)); 318f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 319f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 320f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Posts the next task from the |task_queue_|, unless it is exhausted, in 321f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // which case it posts |callback_| to return with the results. 322f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void PostNextTask() { 323f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::Closure next_task; 324f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (task_queue_.empty()) { 325f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) next_task = base::Bind(callback_, base::Passed(&data_)); 326f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else { 327f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) next_task = task_queue_.front(); 328f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) task_queue_.pop(); 329f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 330f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) content::BrowserThread::PostTask( 331f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) content::BrowserThread::UI, FROM_HERE, next_task); 332f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 333f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 334f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) Profile* profile_; 335f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) AutomaticProfileResetterDelegate* delegate_; 336f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ProgramInputCallback callback_; 337f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 338f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PreferenceHostedPromptMemento memento_in_prefs_; 339f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) LocalStateHostedPromptMemento memento_in_local_state_; 340f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) FileHostedPromptMemento memento_in_file_; 341f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 342f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<base::DictionaryValue> data_; 343f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::queue<base::Closure> task_queue_; 344f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 345f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(InputBuilder); 346f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}; 347f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 348f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 349f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// AutomaticProfileResetter::EvaluationResults ------------------------------- 350f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 351f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Encapsulates the output values extracted from the evaluator program. 352f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)struct AutomaticProfileResetter::EvaluationResults { 353f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EvaluationResults() 354a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) : should_prompt(false), 355a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) had_prompted_already(false), 356f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) satisfied_criteria_mask(0), 357f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) combined_status_mask(0) {} 358f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 359f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::string memento_value_in_prefs; 360f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::string memento_value_in_local_state; 361f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::string memento_value_in_file; 362f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 363a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bool should_prompt; 364f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool had_prompted_already; 365f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) uint32 satisfied_criteria_mask; 366f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) uint32 combined_status_mask; 367f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}; 368f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 369f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 3704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// AutomaticProfileResetter -------------------------------------------------- 3714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)AutomaticProfileResetter::AutomaticProfileResetter(Profile* profile) 3734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) : profile_(profile), 3744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) state_(STATE_UNINITIALIZED), 3751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) enumeration_of_loaded_modules_ready_(false), 3761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) template_url_service_ready_(false), 377f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) has_already_dismissed_prompt_(false), 3785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) should_show_reset_banner_(false), 3794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) weak_ptr_factory_(this) { 3804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(profile_); 3814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 3824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)AutomaticProfileResetter::~AutomaticProfileResetter() {} 3844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 385f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void AutomaticProfileResetter::Initialize() { 386f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 387f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK_EQ(state_, STATE_UNINITIALIZED); 388f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 389f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!ShouldPerformDryRun() && !ShouldPerformLiveRun()) { 390f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) state_ = STATE_DISABLED; 391f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 392f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 393f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 394f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!GetProgramAndHashSeedOverridesFromExperiment(&program_, &hash_seed_)) { 395f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ui::ResourceBundle& resources(ui::ResourceBundle::GetSharedInstance()); 396f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (ShouldPerformLiveRun()) { 397f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) program_ = resources.GetRawDataResource( 398f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) IDR_AUTOMATIC_PROFILE_RESET_RULES).as_string(); 399f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hash_seed_ = resources.GetRawDataResource( 400f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) IDR_AUTOMATIC_PROFILE_RESET_HASH_SEED).as_string(); 401f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else { // ShouldPerformDryRun() 402f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) program_ = resources.GetRawDataResource( 403f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) IDR_AUTOMATIC_PROFILE_RESET_RULES_DRY).as_string(); 404f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hash_seed_ = resources.GetRawDataResource( 405f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) IDR_AUTOMATIC_PROFILE_RESET_HASH_SEED_DRY).as_string(); 406f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 407f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 408f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 409f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) delegate_.reset(new AutomaticProfileResetterDelegateImpl( 410f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) profile_, ProfileResetter::ALL)); 411f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) task_runner_for_waiting_ = 412f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) content::BrowserThread::GetMessageLoopProxyForThread( 413f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) content::BrowserThread::UI); 414f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 415f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) state_ = STATE_INITIALIZED; 416f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 417f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 4181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void AutomaticProfileResetter::Activate() { 4191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 4201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK(state_ == STATE_INITIALIZED || state_ == STATE_DISABLED); 4211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 4221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (state_ == STATE_INITIALIZED) { 4231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (!program_.empty()) { 4241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Some steps in the flow (e.g. loaded modules, file-based memento) are 4251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // IO-intensive, so defer execution until some time later. 4261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) task_runner_for_waiting_->PostDelayedTask( 4271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) FROM_HERE, 4281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) base::Bind(&AutomaticProfileResetter::PrepareEvaluationFlow, 4291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr()), 4301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) base::TimeDelta::FromSeconds(kEvaluationFlowDelayInSeconds)); 4311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } else { 4321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Terminate early if there is no program included (nor set by tests). 4331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) state_ = STATE_DISABLED; 4341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 4351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 4361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 4371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 438f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void AutomaticProfileResetter::TriggerProfileReset(bool send_feedback) { 439f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 440f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK_EQ(state_, STATE_HAS_SHOWN_BUBBLE); 441f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 442f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) state_ = STATE_PERFORMING_RESET; 4435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) should_show_reset_banner_ = false; 444f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 445f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ReportPromptResult(PROMPT_ACTION_RESET); 446f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) delegate_->TriggerProfileSettingsReset( 447f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) send_feedback, 448f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::Bind(&AutomaticProfileResetter::OnProfileSettingsResetCompleted, 449f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 450f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 451f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 452f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void AutomaticProfileResetter::SkipProfileReset() { 453f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 454f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK_EQ(state_, STATE_HAS_SHOWN_BUBBLE); 455f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 4565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) should_show_reset_banner_ = false; 4575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 458f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ReportPromptResult(PROMPT_ACTION_NO_RESET); 459f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) delegate_->DismissPrompt(); 460f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) FinishResetPromptFlow(); 461f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 462f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 463f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool AutomaticProfileResetter::IsResetPromptFlowActive() const { 464f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return state_ == STATE_HAS_TRIGGERED_PROMPT || 465f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) state_ == STATE_HAS_SHOWN_BUBBLE; 466f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 467f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 4685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool AutomaticProfileResetter::ShouldShowResetBanner() const { 4695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 4705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return should_show_reset_banner_ && ShouldPerformLiveRun(); 4715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 4725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 473f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void AutomaticProfileResetter::NotifyDidShowResetBubble() { 474f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 475f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK_EQ(state_, STATE_HAS_TRIGGERED_PROMPT); 476f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 477f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) state_ = STATE_HAS_SHOWN_BUBBLE; 478f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 479f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PersistMementos(); 480f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ReportPromptResult(PROMPT_SHOWN_BUBBLE); 481f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 482f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 483f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void AutomaticProfileResetter::NotifyDidOpenWebUIResetDialog() { 484f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 485f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 486f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // This notification is invoked unconditionally by the WebUI, only care about 487f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // it when the prompt flow is currently active (and not yet resetting). 488f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (state_ == STATE_HAS_TRIGGERED_PROMPT || 489f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) state_ == STATE_HAS_SHOWN_BUBBLE) { 490f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) has_already_dismissed_prompt_ = true; 491f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) delegate_->DismissPrompt(); 492f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 493f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 494f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 495f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void AutomaticProfileResetter::NotifyDidCloseWebUIResetDialog( 496f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool performed_reset) { 497f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 498f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 499f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // This notification is invoked unconditionally by the WebUI, only care about 500f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // it when the prompt flow is currently active (and not yet resetting). 501f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (state_ == STATE_HAS_TRIGGERED_PROMPT || 502f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) state_ == STATE_HAS_SHOWN_BUBBLE) { 503f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!has_already_dismissed_prompt_) 504f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) delegate_->DismissPrompt(); 505f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (state_ == STATE_HAS_TRIGGERED_PROMPT) { 506f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PersistMementos(); 507f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ReportPromptResult(performed_reset ? 508f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PROMPT_NOT_SHOWN_BUBBLE_BUT_HAD_WEBUI_RESET : 509f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PROMPT_NOT_SHOWN_BUBBLE_BUT_HAD_WEBUI_NO_RESET); 510f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else { // if (state_ == STATE_HAS_SHOWN_PROMPT) 511f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ReportPromptResult(performed_reset ? 512f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PROMPT_FOLLOWED_BY_WEBUI_RESET : 513f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PROMPT_FOLLOWED_BY_WEBUI_NO_RESET); 514f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 515f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) FinishResetPromptFlow(); 516f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 5171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 5181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 5195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AutomaticProfileResetter::NotifyDidCloseWebUIResetBanner() { 5205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 5215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) should_show_reset_banner_ = false; 5225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 5235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void AutomaticProfileResetter::SetProgramForTesting( 525f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const std::string& program) { 5261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) program_ = program; 5271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 5281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 529f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void AutomaticProfileResetter::SetHashSeedForTesting( 530f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const std::string& hash_key) { 531f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hash_seed_ = hash_key; 532f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 533f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 5341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void AutomaticProfileResetter::SetDelegateForTesting( 5351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) scoped_ptr<AutomaticProfileResetterDelegate> delegate) { 5361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) delegate_ = delegate.Pass(); 5371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 5381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 5391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void AutomaticProfileResetter::SetTaskRunnerForWaitingForTesting( 5401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const scoped_refptr<base::TaskRunner>& task_runner) { 5411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) task_runner_for_waiting_ = task_runner; 5421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 5431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 544f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void AutomaticProfileResetter::Shutdown() { 5454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 5464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 547f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // We better not do anything substantial at this point. The metrics service 548f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // has already been shut down; and local state has already been commited to 549f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // file (in the regular fashion) for the last time. 550f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 551f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) state_ = STATE_DISABLED; 552f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 553f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) weak_ptr_factory_.InvalidateWeakPtrs(); 554f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) delegate_.reset(); 5551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 5564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 5571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void AutomaticProfileResetter::PrepareEvaluationFlow() { 5581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 5591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK_EQ(state_, STATE_INITIALIZED); 5601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 5611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) state_ = STATE_WAITING_ON_DEPENDENCIES; 5621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 5631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) delegate_->RequestCallbackWhenTemplateURLServiceIsLoaded( 5641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) base::Bind(&AutomaticProfileResetter::OnTemplateURLServiceIsLoaded, 5651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 5661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) delegate_->RequestCallbackWhenLoadedModulesAreEnumerated( 5671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) base::Bind(&AutomaticProfileResetter::OnLoadedModulesAreEnumerated, 5681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 5691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) delegate_->LoadTemplateURLServiceIfNeeded(); 5701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) delegate_->EnumerateLoadedModulesIfNeeded(); 5711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 5721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 5731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void AutomaticProfileResetter::OnTemplateURLServiceIsLoaded() { 5741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) template_url_service_ready_ = true; 5751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) OnDependencyIsReady(); 5761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 5771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 5781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void AutomaticProfileResetter::OnLoadedModulesAreEnumerated() { 5791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) enumeration_of_loaded_modules_ready_ = true; 5801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) OnDependencyIsReady(); 5811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 5821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 5831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void AutomaticProfileResetter::OnDependencyIsReady() { 5841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 5851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK_EQ(state_, STATE_WAITING_ON_DEPENDENCIES); 5864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 5871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (template_url_service_ready_ && enumeration_of_loaded_modules_ready_) { 5881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) state_ = STATE_READY; 5894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) content::BrowserThread::PostTask( 5904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) content::BrowserThread::UI, 5914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) FROM_HERE, 5924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::Bind(&AutomaticProfileResetter::BeginEvaluationFlow, 5934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 5944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 5954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 5964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 5974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void AutomaticProfileResetter::BeginEvaluationFlow() { 5984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 5994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK_EQ(state_, STATE_READY); 6001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK(!program_.empty()); 601f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(!input_builder_); 602f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 603f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) state_ = STATE_EVALUATING_CONDITIONS; 6044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 605f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) input_builder_.reset(new InputBuilder(profile_, delegate_.get())); 606f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) input_builder_->BuildEvaluatorProgramInput( 6071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) base::Bind(&AutomaticProfileResetter::ContinueWithEvaluationFlow, 6081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 6094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 6104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 6114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void AutomaticProfileResetter::ContinueWithEvaluationFlow( 612f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<base::DictionaryValue> program_input) { 6134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 614f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK_EQ(state_, STATE_EVALUATING_CONDITIONS); 6154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 616f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) input_builder_.reset(); 6174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 6184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::SequencedWorkerPool* blocking_pool = 6194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) content::BrowserThread::GetBlockingPool(); 6204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) scoped_refptr<base::TaskRunner> task_runner = 6214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) blocking_pool->GetTaskRunnerWithShutdownBehavior( 6224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); 6234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 6244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::PostTaskAndReplyWithResult( 6254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) task_runner.get(), 6264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) FROM_HERE, 6274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::Bind(&EvaluateConditionsOnWorkerPoolThread, 6284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) hash_seed_, 6294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) program_, 630f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::Passed(&program_input)), 6314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::Bind(&AutomaticProfileResetter::FinishEvaluationFlow, 6324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 6334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 6344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 6354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// static 6364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)scoped_ptr<AutomaticProfileResetter::EvaluationResults> 6371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) AutomaticProfileResetter::EvaluateConditionsOnWorkerPoolThread( 638f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const std::string& hash_seed, 639f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const std::string& program, 6404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) scoped_ptr<base::DictionaryValue> program_input) { 641f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) JtlInterpreter interpreter(hash_seed, program, program_input.get()); 6424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) interpreter.Execute(); 6434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("AutomaticProfileReset.InterpreterResult", 6444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) interpreter.result(), 6454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) JtlInterpreter::RESULT_MAX); 6465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) UMA_HISTOGRAM_SPARSE_SLOWLY("AutomaticProfileReset.ProgramChecksum", 6475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) interpreter.CalculateProgramChecksum()); 6484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 6494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // In each case below, the respective field in result originally contains the 6504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // default, so if the getter fails, we still have the correct value there. 6511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) scoped_ptr<EvaluationResults> results(new EvaluationResults); 652a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) interpreter.GetOutputBoolean(kShouldPromptKey, &results->should_prompt); 6534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) interpreter.GetOutputBoolean(kHadPromptedAlreadyKey, 6544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) &results->had_prompted_already); 6554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) interpreter.GetOutputString(kMementoValueInPrefsKey, 6564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) &results->memento_value_in_prefs); 6574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) interpreter.GetOutputString(kMementoValueInLocalStateKey, 6584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) &results->memento_value_in_local_state); 6594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) interpreter.GetOutputString(kMementoValueInFileKey, 6604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) &results->memento_value_in_file); 661a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) for (size_t i = 0; i < kCombinedStatusMaskNumberOfBits; ++i) { 6624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool flag = false; 663a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) std::string mask_i_th_bit_key = 664a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) kCombinedStatusMaskKeyPrefix + base::IntToString(i + 1); 665a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (interpreter.GetOutputBoolean(mask_i_th_bit_key, &flag) && flag) 6664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) results->combined_status_mask |= (1 << i); 6674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 668a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) for (size_t i = 0; i < kSatisfiedCriteriaMaskNumberOfBits; ++i) { 6694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool flag = false; 670a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) std::string mask_i_th_bit_key = 671a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) kSatisfiedCriteriaMaskKeyPrefix + base::IntToString(i + 1); 672a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (interpreter.GetOutputBoolean(mask_i_th_bit_key, &flag) && flag) 6734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) results->satisfied_criteria_mask |= (1 << i); 6744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 6754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return results.Pass(); 6764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 6774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 678f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void AutomaticProfileResetter::ReportStatistics(uint32 satisfied_criteria_mask, 679f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) uint32 combined_status_mask) { 680f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("AutomaticProfileReset.SatisfiedCriteriaMask", 681f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) satisfied_criteria_mask, 682f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) kSatisfiedCriteriaMaskMaximumValue); 683f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("AutomaticProfileReset.CombinedStatusMask", 684f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) combined_status_mask, 685f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) kCombinedStatusMaskMaximumValue); 686f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 687f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 6884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void AutomaticProfileResetter::FinishEvaluationFlow( 6894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) scoped_ptr<EvaluationResults> results) { 6904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 691f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK_EQ(state_, STATE_EVALUATING_CONDITIONS); 6924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 6931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) ReportStatistics(results->satisfied_criteria_mask, 6941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) results->combined_status_mask); 6954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 6965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (results->should_prompt) 6975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) should_show_reset_banner_ = true; 6985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 699a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (results->should_prompt && !results->had_prompted_already) { 700f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) evaluation_results_ = results.Pass(); 701f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) BeginResetPromptFlow(); 702f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else { 703f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) state_ = STATE_DONE; 704f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 705f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 7064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 707f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void AutomaticProfileResetter::BeginResetPromptFlow() { 708f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 709f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK_EQ(state_, STATE_EVALUATING_CONDITIONS); 710f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 711f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) state_ = STATE_HAS_TRIGGERED_PROMPT; 712f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 713f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (ShouldPerformLiveRun() && delegate_->TriggerPrompt()) { 714f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Start fetching the brandcoded default settings speculatively in the 715f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // background, so as to reduce waiting time if the user chooses to go 716f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // through with the reset. 717f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) delegate_->FetchBrandcodedDefaultSettingsIfNeeded(); 718f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else { 719f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PersistMementos(); 720f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ReportPromptResult(PROMPT_NOT_TRIGGERED); 721f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) FinishResetPromptFlow(); 7224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 723f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 7244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 725f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void AutomaticProfileResetter::OnProfileSettingsResetCompleted() { 726f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 727f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK_EQ(state_, STATE_PERFORMING_RESET); 728f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 729f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) delegate_->DismissPrompt(); 730f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) FinishResetPromptFlow(); 7314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 7324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 733f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void AutomaticProfileResetter::ReportPromptResult(PromptResult result) { 734f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) UMA_HISTOGRAM_ENUMERATION( 735f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) "AutomaticProfileReset.PromptResult", result, PROMPT_RESULT_MAX); 7364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 7374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 738f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void AutomaticProfileResetter::PersistMementos() { 7394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 740f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(state_ == STATE_HAS_TRIGGERED_PROMPT || 741f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) state_ == STATE_HAS_SHOWN_BUBBLE); 742f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(evaluation_results_); 7434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 744f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PreferenceHostedPromptMemento memento_in_prefs(profile_); 745f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) LocalStateHostedPromptMemento memento_in_local_state(profile_); 746f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) FileHostedPromptMemento memento_in_file(profile_); 747f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 748f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) memento_in_prefs.StoreValue(evaluation_results_->memento_value_in_prefs); 749f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) memento_in_local_state.StoreValue( 750f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) evaluation_results_->memento_value_in_local_state); 751f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) memento_in_file.StoreValue(evaluation_results_->memento_value_in_file); 752f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 753f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) evaluation_results_.reset(); 754f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 755f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 756f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void AutomaticProfileResetter::FinishResetPromptFlow() { 757f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 758f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(state_ == STATE_HAS_TRIGGERED_PROMPT || 759f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) state_ == STATE_HAS_SHOWN_BUBBLE || 760f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) state_ == STATE_PERFORMING_RESET); 761f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(!evaluation_results_); 762f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 763f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) state_ = STATE_DONE; 7644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 765