| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/profile_resetter/automatic_profile_resetter.h" | 5 #include "chrome/browser/profile_resetter/automatic_profile_resetter.h" |
| 6 | 6 |
| 7 #include "base/bind_helpers.h" | 7 #include "base/bind_helpers.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/memory/ref_counted.h" | 9 #include "base/memory/ref_counted.h" |
| 10 #include "base/metrics/field_trial.h" | 10 #include "base/metrics/field_trial.h" |
| 11 #include "base/metrics/histogram.h" | 11 #include "base/metrics/histogram.h" |
| 12 #include "base/prefs/pref_service.h" | 12 #include "base/prefs/pref_service.h" |
| 13 #include "base/strings/string_number_conversions.h" |
| 13 #include "base/task_runner.h" | 14 #include "base/task_runner.h" |
| 14 #include "base/task_runner_util.h" | 15 #include "base/task_runner_util.h" |
| 15 #include "base/threading/sequenced_worker_pool.h" | 16 #include "base/threading/sequenced_worker_pool.h" |
| 17 #include "base/time/time.h" |
| 18 #include "base/values.h" |
| 19 #include "chrome/browser/browser_process.h" |
| 20 #include "chrome/browser/profile_resetter/automatic_profile_resetter_delegate.h" |
| 16 #include "chrome/browser/profile_resetter/jtl_interpreter.h" | 21 #include "chrome/browser/profile_resetter/jtl_interpreter.h" |
| 17 #include "chrome/browser/profiles/profile.h" | 22 #include "chrome/browser/profiles/profile.h" |
| 18 #include "content/public/browser/browser_thread.h" | 23 #include "content/public/browser/browser_thread.h" |
| 19 #include "grit/browser_resources.h" | 24 #include "grit/browser_resources.h" |
| 20 #include "ui/base/resource/resource_bundle.h" | 25 #include "ui/base/resource/resource_bundle.h" |
| 21 | 26 |
| 22 namespace { | 27 namespace { |
| 23 | 28 |
| 24 // Number of bits, and maximum value (exclusive) for the mask whose bits | |
| 25 // indicate which of reset criteria were satisfied. | |
| 26 const size_t kSatisfiedCriteriaMaskBits = 2; | |
| 27 const uint32 kSatisfiedCriteriaMaskMaximumValue = | |
| 28 (1 << kSatisfiedCriteriaMaskBits); | |
| 29 | |
| 30 // Number of bits, and maximum value (exclusive) for the mask whose bits | |
| 31 // indicate if any of reset criteria were satisfied, and which of the mementos | |
| 32 // were already present. | |
| 33 const size_t kCombinedStatusMaskBits = 4; | |
| 34 const uint32 kCombinedStatusMaskMaximumValue = (1 << kCombinedStatusMaskBits); | |
| 35 | |
| 36 // Name constants for the field trial behind which we enable this feature. | 29 // Name constants for the field trial behind which we enable this feature. |
| 37 const char kAutomaticProfileResetStudyName[] = "AutomaticProfileReset"; | 30 const char kAutomaticProfileResetStudyName[] = "AutomaticProfileReset"; |
| 38 const char kAutomaticProfileResetStudyDryRunGroupName[] = "DryRun"; | 31 const char kAutomaticProfileResetStudyDryRunGroupName[] = "DryRun"; |
| 39 const char kAutomaticProfileResetStudyEnabledGroupName[] = "Enabled"; | 32 const char kAutomaticProfileResetStudyEnabledGroupName[] = "Enabled"; |
| 40 | 33 |
| 34 // How long to wait after start-up before unleashing the evaluation flow. |
| 35 const int64 kEvaluationFlowDelayInSeconds = 55; |
| 36 |
| 41 // Keys used in the input dictionary of the program. | 37 // Keys used in the input dictionary of the program. |
| 42 // TODO(engedy): Add these here on an as-needed basis. | 38 const char kUserPreferencesKey[] = "preferences"; |
| 39 const char kUserPreferencesIsUserControlledKey[] = "preferences_iuc"; |
| 40 const char kLocalStateKey[] = "local_state"; |
| 41 const char kLocalStateIsUserControlledKey[] = "local_state_iuc"; |
| 42 const char kSearchProvidersKey[] = "search_providers"; |
| 43 const char kDefaultSearchProviderKey[] = "default_search_provider"; |
| 44 const char kDefaultSearchProviderIsUserControlledKey[] = |
| 45 "default_search_provider_iuc"; |
| 46 const char kLoadedModuleDigestsKey[] = "loaded_modules"; |
| 43 | 47 |
| 44 // Keys used in the output dictionary of the program. | 48 // Keys used in the output dictionary of the program. |
| 45 const char kHadPromptedAlreadyKey[] = "had_prompted_already"; | 49 const char kHadPromptedAlreadyKey[] = "had_prompted_already"; |
| 46 const char kSatisfiedCriteriaMaskKeys[][29] = {"satisfied_criteria_mask_bit1", | 50 const char kSatisfiedCriteriaMaskKeys[][29] = {"satisfied_criteria_mask_bit1", |
| 47 "satisfied_criteria_mask_bit2"}; | 51 "satisfied_criteria_mask_bit2"}; |
| 48 const char kCombinedStatusMaskKeys[][26] = { | 52 const char kCombinedStatusMaskKeys[][26] = { |
| 49 "combined_status_mask_bit1", "combined_status_mask_bit2", | 53 "combined_status_mask_bit1", "combined_status_mask_bit2", |
| 50 "combined_status_mask_bit3", "combined_status_mask_bit4"}; | 54 "combined_status_mask_bit3", "combined_status_mask_bit4"}; |
| 51 | 55 |
| 52 // Keys used in both the input and output dictionary of the program. | 56 // Keys used in both the input and output dictionary of the program. |
| 53 const char kMementoValueInPrefsKey[] = "memento_value_in_prefs"; | 57 const char kMementoValueInPrefsKey[] = "memento_value_in_prefs"; |
| 54 const char kMementoValueInLocalStateKey[] = "memento_value_in_local_state"; | 58 const char kMementoValueInLocalStateKey[] = "memento_value_in_local_state"; |
| 55 const char kMementoValueInFileKey[] = "memento_value_in_file"; | 59 const char kMementoValueInFileKey[] = "memento_value_in_file"; |
| 56 | 60 |
| 57 COMPILE_ASSERT( | 61 // Implementation details ------------------------------------------------------ |
| 58 arraysize(kSatisfiedCriteriaMaskKeys) == kSatisfiedCriteriaMaskBits, | |
| 59 satisfied_criteria_mask_bits_mismatch); | |
| 60 COMPILE_ASSERT(arraysize(kCombinedStatusMaskKeys) == kCombinedStatusMaskBits, | |
| 61 combined_status_mask_bits_mismatch); | |
| 62 | |
| 63 // Implementation detail classes --------------------------------------------- | |
| 64 | |
| 65 class AutomaticProfileResetterDelegateImpl | |
| 66 : public AutomaticProfileResetterDelegate { | |
| 67 public: | |
| 68 AutomaticProfileResetterDelegateImpl() {} | |
| 69 virtual ~AutomaticProfileResetterDelegateImpl() {} | |
| 70 | |
| 71 // AutomaticProfileResetterDelegate overrides: | |
| 72 | |
| 73 virtual void ShowPrompt() OVERRIDE { | |
| 74 // TODO(engedy): Call the UI from here once we have it. | |
| 75 } | |
| 76 | |
| 77 virtual void ReportStatistics(uint32 satisfied_criteria_mask, | |
| 78 uint32 combined_status_mask) OVERRIDE { | |
| 79 UMA_HISTOGRAM_ENUMERATION("AutomaticProfileReset.SatisfiedCriteriaMask", | |
| 80 satisfied_criteria_mask, | |
| 81 kSatisfiedCriteriaMaskMaximumValue); | |
| 82 UMA_HISTOGRAM_ENUMERATION("AutomaticProfileReset.CombinedStatusMask", | |
| 83 combined_status_mask, | |
| 84 kCombinedStatusMaskMaximumValue); | |
| 85 } | |
| 86 | |
| 87 private: | |
| 88 DISALLOW_COPY_AND_ASSIGN(AutomaticProfileResetterDelegateImpl); | |
| 89 }; | |
| 90 | 62 |
| 91 // Enumeration of the possible outcomes of showing the profile reset prompt. | 63 // Enumeration of the possible outcomes of showing the profile reset prompt. |
| 92 enum PromptResult { | 64 enum PromptResult { |
| 93 // Prompt was not shown because only a dry-run was performed. | 65 // Prompt was not shown because only a dry-run was performed. |
| 94 PROMPT_NOT_SHOWN, | 66 PROMPT_NOT_SHOWN, |
| 95 PROMPT_ACTION_RESET, | 67 PROMPT_ACTION_RESET, |
| 96 PROMPT_ACTION_NO_RESET, | 68 PROMPT_ACTION_NO_RESET, |
| 97 PROMPT_DISMISSED, | 69 PROMPT_DISMISSED, |
| 98 // Prompt was still shown (not dismissed by the user) when Chrome was closed. | 70 // Prompt was still shown (not dismissed by the user) when Chrome was closed. |
| 99 PROMPT_IGNORED, | 71 PROMPT_IGNORED, |
| 100 PROMPT_RESULT_MAX | 72 PROMPT_RESULT_MAX |
| 101 }; | 73 }; |
| 102 | 74 |
| 75 // Returns whether or not a dry-run shall be performed. |
| 76 bool ShouldPerformDryRun() { |
| 77 return base::FieldTrialList::FindFullName(kAutomaticProfileResetStudyName) == |
| 78 kAutomaticProfileResetStudyDryRunGroupName; |
| 79 } |
| 80 |
| 81 // Returns whether or not a live-run shall be performed. |
| 82 bool ShouldPerformLiveRun() { |
| 83 return base::FieldTrialList::FindFullName(kAutomaticProfileResetStudyName) == |
| 84 kAutomaticProfileResetStudyEnabledGroupName; |
| 85 } |
| 86 |
| 87 // Deep-copies all preferences in |source| to a sub-tree named |value_tree_key| |
| 88 // in |target_dictionary|, with path expansion, and also creates an isomorphic |
| 89 // sub-tree under the key |is_user_controlled_tree_key| that contains only |
| 90 // Boolean values, indicating whether or not the corresponding preferences are |
| 91 // coming from the 'user' PrefStore. |
| 92 void BuildSubTreesFromPreferences(const PrefService* source, |
| 93 const char* value_tree_key, |
| 94 const char* is_user_controlled_tree_key, |
| 95 base::DictionaryValue* target_dictionary) { |
| 96 scoped_ptr<base::DictionaryValue> pref_name_to_value_map( |
| 97 source->GetPreferenceValuesWithoutPathExpansion()); |
| 98 std::vector<std::string> pref_names; |
| 99 pref_names.reserve(pref_name_to_value_map->size()); |
| 100 for (base::DictionaryValue::Iterator it(*pref_name_to_value_map); |
| 101 !it.IsAtEnd(); it.Advance()) |
| 102 pref_names.push_back(it.key()); |
| 103 |
| 104 base::DictionaryValue* value_tree = new base::DictionaryValue; |
| 105 base::DictionaryValue* is_user_controlled_tree = new base::DictionaryValue; |
| 106 for (std::vector<std::string>::const_iterator it = pref_names.begin(); |
| 107 it != pref_names.end(); ++it) { |
| 108 scoped_ptr<Value> pref_value_owned; |
| 109 if (pref_name_to_value_map->RemoveWithoutPathExpansion(*it, |
| 110 &pref_value_owned)) { |
| 111 value_tree->Set(*it, pref_value_owned.release()); |
| 112 const PrefService::Preference* pref = source->FindPreference(it->c_str()); |
| 113 is_user_controlled_tree->Set( |
| 114 *it, new base::FundamentalValue(pref->IsUserControlled())); |
| 115 } |
| 116 } |
| 117 target_dictionary->Set(value_tree_key, value_tree); |
| 118 target_dictionary->Set(is_user_controlled_tree_key, is_user_controlled_tree); |
| 119 } |
| 120 |
| 103 } // namespace | 121 } // namespace |
| 104 | 122 |
| 105 // AutomaticProfileResetter::EvaluationResults ------------------------------- | 123 // AutomaticProfileResetter::EvaluationResults ------------------------------- |
| 106 | 124 |
| 107 // Encapsulates the output values extracted from the evaluator program. | 125 // Encapsulates the output values extracted from the evaluator program. |
| 108 struct AutomaticProfileResetter::EvaluationResults { | 126 struct AutomaticProfileResetter::EvaluationResults { |
| 109 EvaluationResults() | 127 EvaluationResults() |
| 110 : had_prompted_already(false), | 128 : had_prompted_already(false), |
| 111 satisfied_criteria_mask(0), | 129 satisfied_criteria_mask(0), |
| 112 combined_status_mask(0) {} | 130 combined_status_mask(0) {} |
| 113 | 131 |
| 114 std::string memento_value_in_prefs; | 132 std::string memento_value_in_prefs; |
| 115 std::string memento_value_in_local_state; | 133 std::string memento_value_in_local_state; |
| 116 std::string memento_value_in_file; | 134 std::string memento_value_in_file; |
| 117 | 135 |
| 118 bool had_prompted_already; | 136 bool had_prompted_already; |
| 119 uint32 satisfied_criteria_mask; | 137 uint32 satisfied_criteria_mask; |
| 120 uint32 combined_status_mask; | 138 uint32 combined_status_mask; |
| 121 }; | 139 }; |
| 122 | 140 |
| 123 // AutomaticProfileResetter -------------------------------------------------- | 141 // AutomaticProfileResetter -------------------------------------------------- |
| 124 | 142 |
| 143 const size_t AutomaticProfileResetter::kSatisfiedCriteriaMaskNumberOfBits = 2u; |
| 144 const uint32 AutomaticProfileResetter::kSatisfiedCriteriaMaskMaximumValue = |
| 145 (1u << AutomaticProfileResetter::kSatisfiedCriteriaMaskNumberOfBits); |
| 146 |
| 147 const size_t AutomaticProfileResetter::kCombinedStatusMaskNumberOfBits = 4u; |
| 148 const uint32 AutomaticProfileResetter::kCombinedStatusMaskMaximumValue = |
| 149 (1u << AutomaticProfileResetter::kCombinedStatusMaskNumberOfBits); |
| 150 |
| 151 COMPILE_ASSERT(arraysize(kSatisfiedCriteriaMaskKeys) == |
| 152 AutomaticProfileResetter::kSatisfiedCriteriaMaskNumberOfBits, |
| 153 satisfied_criteria_mask_bits_mismatch); |
| 154 COMPILE_ASSERT(arraysize(kCombinedStatusMaskKeys) == |
| 155 AutomaticProfileResetter::kCombinedStatusMaskNumberOfBits, |
| 156 combined_status_mask_bits_mismatch); |
| 157 |
| 125 AutomaticProfileResetter::AutomaticProfileResetter(Profile* profile) | 158 AutomaticProfileResetter::AutomaticProfileResetter(Profile* profile) |
| 126 : profile_(profile), | 159 : profile_(profile), |
| 127 state_(STATE_UNINITIALIZED), | 160 state_(STATE_UNINITIALIZED), |
| 161 enumeration_of_loaded_modules_ready_(false), |
| 162 template_url_service_ready_(false), |
| 128 memento_in_prefs_(profile_), | 163 memento_in_prefs_(profile_), |
| 129 memento_in_local_state_(profile_), | 164 memento_in_local_state_(profile_), |
| 130 memento_in_file_(profile_), | 165 memento_in_file_(profile_), |
| 131 weak_ptr_factory_(this) { | 166 weak_ptr_factory_(this) { |
| 132 DCHECK(profile_); | 167 DCHECK(profile_); |
| 168 Initialize(); |
| 133 } | 169 } |
| 134 | 170 |
| 135 AutomaticProfileResetter::~AutomaticProfileResetter() {} | 171 AutomaticProfileResetter::~AutomaticProfileResetter() {} |
| 136 | 172 |
| 137 void AutomaticProfileResetter::Initialize() { | 173 void AutomaticProfileResetter::Initialize() { |
| 138 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 174 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 139 DCHECK_EQ(state_, STATE_UNINITIALIZED); | 175 DCHECK_EQ(state_, STATE_UNINITIALIZED); |
| 140 | 176 |
| 141 if (ShouldPerformDryRun() || ShouldPerformLiveRun()) { | 177 if (ShouldPerformDryRun() || ShouldPerformLiveRun()) { |
| 142 ui::ResourceBundle& resources(ui::ResourceBundle::GetSharedInstance()); | 178 ui::ResourceBundle& resources(ui::ResourceBundle::GetSharedInstance()); |
| 143 if (ShouldPerformLiveRun()) { | 179 if (ShouldPerformLiveRun()) { |
| 144 program_ = | 180 program_ = |
| 145 resources.GetRawDataResource(IDR_AUTOMATIC_PROFILE_RESET_RULES); | 181 resources.GetRawDataResource(IDR_AUTOMATIC_PROFILE_RESET_RULES); |
| 146 hash_seed_ = | 182 hash_seed_ = |
| 147 resources.GetRawDataResource(IDR_AUTOMATIC_PROFILE_RESET_HASH_SEED); | 183 resources.GetRawDataResource(IDR_AUTOMATIC_PROFILE_RESET_HASH_SEED); |
| 148 } else { // ShouldPerformDryRun() | 184 } else { // ShouldPerformDryRun() |
| 149 program_ = | 185 program_ = |
| 150 resources.GetRawDataResource(IDR_AUTOMATIC_PROFILE_RESET_RULES_DRY); | 186 resources.GetRawDataResource(IDR_AUTOMATIC_PROFILE_RESET_RULES_DRY); |
| 151 hash_seed_ = resources.GetRawDataResource( | 187 hash_seed_ = resources.GetRawDataResource( |
| 152 IDR_AUTOMATIC_PROFILE_RESET_HASH_SEED_DRY); | 188 IDR_AUTOMATIC_PROFILE_RESET_HASH_SEED_DRY); |
| 153 } | 189 } |
| 154 delegate_.reset(new AutomaticProfileResetterDelegateImpl()); | 190 delegate_.reset(new AutomaticProfileResetterDelegateImpl(profile_)); |
| 191 task_runner_for_waiting_ = |
| 192 content::BrowserThread::GetMessageLoopProxyForThread( |
| 193 content::BrowserThread::UI); |
| 194 state_ = STATE_INITIALIZED; |
| 195 } else { |
| 196 state_ = STATE_DISABLED; |
| 197 } |
| 198 } |
| 155 | 199 |
| 200 void AutomaticProfileResetter::Activate() { |
| 201 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 202 DCHECK(state_ == STATE_INITIALIZED || state_ == STATE_DISABLED); |
| 203 |
| 204 if (state_ == STATE_INITIALIZED) { |
| 205 if (!program_.empty()) { |
| 206 // Some steps in the flow (e.g. loaded modules, file-based memento) are |
| 207 // IO-intensive, so defer execution until some time later. |
| 208 task_runner_for_waiting_->PostDelayedTask( |
| 209 FROM_HERE, |
| 210 base::Bind(&AutomaticProfileResetter::PrepareEvaluationFlow, |
| 211 weak_ptr_factory_.GetWeakPtr()), |
| 212 base::TimeDelta::FromSeconds(kEvaluationFlowDelayInSeconds)); |
| 213 } else { |
| 214 // Terminate early if there is no program included (nor set by tests). |
| 215 state_ = STATE_DISABLED; |
| 216 } |
| 217 } |
| 218 } |
| 219 |
| 220 void AutomaticProfileResetter::PrepareEvaluationFlow() { |
| 221 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 222 DCHECK_EQ(state_, STATE_INITIALIZED); |
| 223 |
| 224 state_ = STATE_WAITING_ON_DEPENDENCIES; |
| 225 |
| 226 delegate_->RequestCallbackWhenTemplateURLServiceIsLoaded( |
| 227 base::Bind(&AutomaticProfileResetter::OnTemplateURLServiceIsLoaded, |
| 228 weak_ptr_factory_.GetWeakPtr())); |
| 229 delegate_->RequestCallbackWhenLoadedModulesAreEnumerated( |
| 230 base::Bind(&AutomaticProfileResetter::OnLoadedModulesAreEnumerated, |
| 231 weak_ptr_factory_.GetWeakPtr())); |
| 232 delegate_->LoadTemplateURLServiceIfNeeded(); |
| 233 delegate_->EnumerateLoadedModulesIfNeeded(); |
| 234 } |
| 235 |
| 236 void AutomaticProfileResetter::OnTemplateURLServiceIsLoaded() { |
| 237 template_url_service_ready_ = true; |
| 238 OnDependencyIsReady(); |
| 239 } |
| 240 |
| 241 void AutomaticProfileResetter::OnLoadedModulesAreEnumerated() { |
| 242 enumeration_of_loaded_modules_ready_ = true; |
| 243 OnDependencyIsReady(); |
| 244 } |
| 245 |
| 246 void AutomaticProfileResetter::OnDependencyIsReady() { |
| 247 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 248 DCHECK_EQ(state_, STATE_WAITING_ON_DEPENDENCIES); |
| 249 |
| 250 if (template_url_service_ready_ && enumeration_of_loaded_modules_ready_) { |
| 156 state_ = STATE_READY; | 251 state_ = STATE_READY; |
| 157 | |
| 158 content::BrowserThread::PostTask( | 252 content::BrowserThread::PostTask( |
| 159 content::BrowserThread::UI, | 253 content::BrowserThread::UI, |
| 160 FROM_HERE, | 254 FROM_HERE, |
| 161 base::Bind(&AutomaticProfileResetter::BeginEvaluationFlow, | 255 base::Bind(&AutomaticProfileResetter::BeginEvaluationFlow, |
| 162 weak_ptr_factory_.GetWeakPtr())); | 256 weak_ptr_factory_.GetWeakPtr())); |
| 163 } else { | |
| 164 state_ = STATE_DISABLED; | |
| 165 } | 257 } |
| 166 } | 258 } |
| 167 | 259 |
| 168 bool AutomaticProfileResetter::ShouldPerformDryRun() const { | |
| 169 return base::FieldTrialList::FindFullName(kAutomaticProfileResetStudyName) == | |
| 170 kAutomaticProfileResetStudyDryRunGroupName; | |
| 171 } | |
| 172 | |
| 173 bool AutomaticProfileResetter::ShouldPerformLiveRun() const { | |
| 174 return base::FieldTrialList::FindFullName(kAutomaticProfileResetStudyName) == | |
| 175 kAutomaticProfileResetStudyEnabledGroupName; | |
| 176 } | |
| 177 | |
| 178 void AutomaticProfileResetter::BeginEvaluationFlow() { | 260 void AutomaticProfileResetter::BeginEvaluationFlow() { |
| 179 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 261 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 180 DCHECK_EQ(state_, STATE_READY); | 262 DCHECK_EQ(state_, STATE_READY); |
| 263 DCHECK(!program_.empty()); |
| 181 | 264 |
| 182 if (!program_.empty()) { | 265 state_ = STATE_WORKING; |
| 183 state_ = STATE_WORKING; | 266 memento_in_file_.ReadValue( |
| 184 memento_in_file_.ReadValue( | 267 base::Bind(&AutomaticProfileResetter::ContinueWithEvaluationFlow, |
| 185 base::Bind(&AutomaticProfileResetter::ContinueWithEvaluationFlow, | 268 weak_ptr_factory_.GetWeakPtr())); |
| 186 weak_ptr_factory_.GetWeakPtr())); | |
| 187 } else { | |
| 188 // Terminate early if there is no program included (nor set by tests). | |
| 189 state_ = STATE_DISABLED; | |
| 190 } | |
| 191 } | 269 } |
| 192 | 270 |
| 193 scoped_ptr<base::DictionaryValue> | 271 scoped_ptr<base::DictionaryValue> |
| 194 AutomaticProfileResetter::BuildEvaluatorProgramInput( | 272 AutomaticProfileResetter::BuildEvaluatorProgramInput( |
| 195 const std::string& memento_value_in_file) { | 273 const std::string& memento_value_in_file) { |
| 196 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 274 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 197 // TODO(engedy): Add any additional state here that is needed by the program. | 275 |
| 198 scoped_ptr<base::DictionaryValue> input(new base::DictionaryValue); | 276 scoped_ptr<base::DictionaryValue> input(new base::DictionaryValue); |
| 277 |
| 278 // Include memento values (or empty strings in case mementos are not there). |
| 199 input->SetString(kMementoValueInPrefsKey, memento_in_prefs_.ReadValue()); | 279 input->SetString(kMementoValueInPrefsKey, memento_in_prefs_.ReadValue()); |
| 200 input->SetString(kMementoValueInLocalStateKey, | 280 input->SetString(kMementoValueInLocalStateKey, |
| 201 memento_in_local_state_.ReadValue()); | 281 memento_in_local_state_.ReadValue()); |
| 202 input->SetString(kMementoValueInFileKey, memento_value_in_file); | 282 input->SetString(kMementoValueInFileKey, memento_value_in_file); |
| 283 |
| 284 // Include all user (i.e. profile-specific) preferences, along with |
| 285 // information about whether the value is coming from the 'user' PrefStore. |
| 286 PrefService* prefs = profile_->GetPrefs(); |
| 287 DCHECK(prefs); |
| 288 BuildSubTreesFromPreferences(prefs, |
| 289 kUserPreferencesKey, |
| 290 kUserPreferencesIsUserControlledKey, |
| 291 input.get()); |
| 292 |
| 293 // Include all local state (i.e. shared) preferences, along with information |
| 294 // about whether the value is coming from the 'user' PrefStore. |
| 295 PrefService* local_state = g_browser_process->local_state(); |
| 296 DCHECK(local_state); |
| 297 BuildSubTreesFromPreferences( |
| 298 local_state, kLocalStateKey, kLocalStateIsUserControlledKey, input.get()); |
| 299 |
| 300 // Include all information related to search engines. |
| 301 scoped_ptr<base::DictionaryValue> default_search_provider_details( |
| 302 delegate_->GetDefaultSearchProviderDetails()); |
| 303 if (default_search_provider_details) |
| 304 input->Set(kDefaultSearchProviderKey, |
| 305 default_search_provider_details.release()); |
| 306 |
| 307 scoped_ptr<base::ListValue> search_providers_details( |
| 308 delegate_->GetPrepopulatedSearchProvidersDetails()); |
| 309 if (search_providers_details) |
| 310 input->Set(kSearchProvidersKey, search_providers_details.release()); |
| 311 |
| 312 input->SetBoolean(kDefaultSearchProviderIsUserControlledKey, |
| 313 !delegate_->IsDefaultSearchProviderManaged()); |
| 314 |
| 315 // Include information about loaded modules. |
| 316 scoped_ptr<base::ListValue> loaded_module_digests( |
| 317 delegate_->GetLoadedModuleNameDigests()); |
| 318 if (loaded_module_digests) |
| 319 input->Set(kLoadedModuleDigestsKey, loaded_module_digests.release()); |
| 320 |
| 203 return input.Pass(); | 321 return input.Pass(); |
| 204 } | 322 } |
| 205 | 323 |
| 206 void AutomaticProfileResetter::ContinueWithEvaluationFlow( | 324 void AutomaticProfileResetter::ContinueWithEvaluationFlow( |
| 207 const std::string& memento_value_in_file) { | 325 const std::string& memento_value_in_file) { |
| 208 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 326 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 209 DCHECK_EQ(state_, STATE_WORKING); | 327 DCHECK_EQ(state_, STATE_WORKING); |
| 210 PrefService* prefs = profile_->GetPrefs(); | 328 PrefService* prefs = profile_->GetPrefs(); |
| 211 DCHECK(prefs); | 329 DCHECK(prefs); |
| 212 | 330 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 225 base::Bind(&EvaluateConditionsOnWorkerPoolThread, | 343 base::Bind(&EvaluateConditionsOnWorkerPoolThread, |
| 226 hash_seed_, | 344 hash_seed_, |
| 227 program_, | 345 program_, |
| 228 base::Passed(&input)), | 346 base::Passed(&input)), |
| 229 base::Bind(&AutomaticProfileResetter::FinishEvaluationFlow, | 347 base::Bind(&AutomaticProfileResetter::FinishEvaluationFlow, |
| 230 weak_ptr_factory_.GetWeakPtr())); | 348 weak_ptr_factory_.GetWeakPtr())); |
| 231 } | 349 } |
| 232 | 350 |
| 233 // static | 351 // static |
| 234 scoped_ptr<AutomaticProfileResetter::EvaluationResults> | 352 scoped_ptr<AutomaticProfileResetter::EvaluationResults> |
| 235 AutomaticProfileResetter::EvaluateConditionsOnWorkerPoolThread( | 353 AutomaticProfileResetter::EvaluateConditionsOnWorkerPoolThread( |
| 236 const base::StringPiece& hash_seed, | 354 const base::StringPiece& hash_seed, |
| 237 const base::StringPiece& program, | 355 const base::StringPiece& program, |
| 238 scoped_ptr<base::DictionaryValue> program_input) { | 356 scoped_ptr<base::DictionaryValue> program_input) { |
| 239 std::string hash_seed_str(hash_seed.as_string()); | 357 std::string hash_seed_str(hash_seed.as_string()); |
| 240 std::string program_str(program.as_string()); | 358 std::string program_str(program.as_string()); |
| 241 JtlInterpreter interpreter(hash_seed_str, program_str, program_input.get()); | 359 JtlInterpreter interpreter(hash_seed_str, program_str, program_input.get()); |
| 242 interpreter.Execute(); | 360 interpreter.Execute(); |
| 243 UMA_HISTOGRAM_ENUMERATION("AutomaticProfileReset.InterpreterResult", | 361 UMA_HISTOGRAM_ENUMERATION("AutomaticProfileReset.InterpreterResult", |
| 244 interpreter.result(), | 362 interpreter.result(), |
| 245 JtlInterpreter::RESULT_MAX); | 363 JtlInterpreter::RESULT_MAX); |
| 246 | 364 |
| 247 // In each case below, the respective field in result originally contains the | 365 // In each case below, the respective field in result originally contains the |
| 248 // default, so if the getter fails, we still have the correct value there. | 366 // default, so if the getter fails, we still have the correct value there. |
| 249 scoped_ptr<EvaluationResults> results(new EvaluationResults()); | 367 scoped_ptr<EvaluationResults> results(new EvaluationResults); |
| 250 interpreter.GetOutputBoolean(kHadPromptedAlreadyKey, | 368 interpreter.GetOutputBoolean(kHadPromptedAlreadyKey, |
| 251 &results->had_prompted_already); | 369 &results->had_prompted_already); |
| 252 interpreter.GetOutputString(kMementoValueInPrefsKey, | 370 interpreter.GetOutputString(kMementoValueInPrefsKey, |
| 253 &results->memento_value_in_prefs); | 371 &results->memento_value_in_prefs); |
| 254 interpreter.GetOutputString(kMementoValueInLocalStateKey, | 372 interpreter.GetOutputString(kMementoValueInLocalStateKey, |
| 255 &results->memento_value_in_local_state); | 373 &results->memento_value_in_local_state); |
| 256 interpreter.GetOutputString(kMementoValueInFileKey, | 374 interpreter.GetOutputString(kMementoValueInFileKey, |
| 257 &results->memento_value_in_file); | 375 &results->memento_value_in_file); |
| 258 for (size_t i = 0; i < arraysize(kCombinedStatusMaskKeys); ++i) { | 376 for (size_t i = 0; i < arraysize(kCombinedStatusMaskKeys); ++i) { |
| 259 bool flag = false; | 377 bool flag = false; |
| 260 if (interpreter.GetOutputBoolean(kCombinedStatusMaskKeys[i], &flag) && flag) | 378 if (interpreter.GetOutputBoolean(kCombinedStatusMaskKeys[i], &flag) && flag) |
| 261 results->combined_status_mask |= (1 << i); | 379 results->combined_status_mask |= (1 << i); |
| 262 } | 380 } |
| 263 for (size_t i = 0; i < arraysize(kSatisfiedCriteriaMaskKeys); ++i) { | 381 for (size_t i = 0; i < arraysize(kSatisfiedCriteriaMaskKeys); ++i) { |
| 264 bool flag = false; | 382 bool flag = false; |
| 265 if (interpreter.GetOutputBoolean(kSatisfiedCriteriaMaskKeys[i], &flag) && | 383 if (interpreter.GetOutputBoolean(kSatisfiedCriteriaMaskKeys[i], &flag) && |
| 266 flag) | 384 flag) |
| 267 results->satisfied_criteria_mask |= (1 << i); | 385 results->satisfied_criteria_mask |= (1 << i); |
| 268 } | 386 } |
| 269 return results.Pass(); | 387 return results.Pass(); |
| 270 } | 388 } |
| 271 | 389 |
| 272 void AutomaticProfileResetter::FinishEvaluationFlow( | 390 void AutomaticProfileResetter::FinishEvaluationFlow( |
| 273 scoped_ptr<EvaluationResults> results) { | 391 scoped_ptr<EvaluationResults> results) { |
| 274 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 392 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 275 DCHECK_EQ(state_, STATE_WORKING); | 393 DCHECK_EQ(state_, STATE_WORKING); |
| 276 | 394 |
| 277 delegate_->ReportStatistics(results->satisfied_criteria_mask, | 395 ReportStatistics(results->satisfied_criteria_mask, |
| 278 results->combined_status_mask); | 396 results->combined_status_mask); |
| 279 | 397 |
| 280 if (results->satisfied_criteria_mask != 0 && !results->had_prompted_already) { | 398 if (results->satisfied_criteria_mask != 0 && !results->had_prompted_already) { |
| 281 memento_in_prefs_.StoreValue(results->memento_value_in_prefs); | 399 memento_in_prefs_.StoreValue(results->memento_value_in_prefs); |
| 282 memento_in_local_state_.StoreValue(results->memento_value_in_local_state); | 400 memento_in_local_state_.StoreValue(results->memento_value_in_local_state); |
| 283 memento_in_file_.StoreValue(results->memento_value_in_file); | 401 memento_in_file_.StoreValue(results->memento_value_in_file); |
| 284 | 402 |
| 285 if (ShouldPerformLiveRun()) { | 403 if (ShouldPerformLiveRun()) { |
| 286 delegate_->ShowPrompt(); | 404 delegate_->ShowPrompt(); |
| 287 } else { | 405 } else { |
| 288 UMA_HISTOGRAM_ENUMERATION("AutomaticProfileReset.PromptResult", | 406 UMA_HISTOGRAM_ENUMERATION("AutomaticProfileReset.PromptResult", |
| 289 PROMPT_NOT_SHOWN, | 407 PROMPT_NOT_SHOWN, |
| 290 PROMPT_RESULT_MAX); | 408 PROMPT_RESULT_MAX); |
| 291 } | 409 } |
| 292 } | 410 } |
| 293 | 411 |
| 294 state_ = STATE_DONE; | 412 state_ = STATE_DONE; |
| 295 } | 413 } |
| 296 | 414 |
| 415 void AutomaticProfileResetter::ReportStatistics(uint32 satisfied_criteria_mask, |
| 416 uint32 combined_status_mask) { |
| 417 UMA_HISTOGRAM_ENUMERATION( |
| 418 "AutomaticProfileReset.SatisfiedCriteriaMask", |
| 419 satisfied_criteria_mask, |
| 420 AutomaticProfileResetter::kSatisfiedCriteriaMaskMaximumValue); |
| 421 UMA_HISTOGRAM_ENUMERATION( |
| 422 "AutomaticProfileReset.CombinedStatusMask", |
| 423 combined_status_mask, |
| 424 AutomaticProfileResetter::kCombinedStatusMaskMaximumValue); |
| 425 } |
| 426 |
| 297 void AutomaticProfileResetter::SetHashSeedForTesting( | 427 void AutomaticProfileResetter::SetHashSeedForTesting( |
| 298 const base::StringPiece& hash_key) { | 428 const base::StringPiece& hash_key) { |
| 299 hash_seed_ = hash_key; | 429 hash_seed_ = hash_key; |
| 300 } | 430 } |
| 301 | 431 |
| 302 void AutomaticProfileResetter::SetProgramForTesting( | 432 void AutomaticProfileResetter::SetProgramForTesting( |
| 303 const base::StringPiece& program) { | 433 const base::StringPiece& program) { |
| 304 program_ = program; | 434 program_ = program; |
| 305 } | 435 } |
| 306 | 436 |
| 307 void AutomaticProfileResetter::SetDelegateForTesting( | 437 void AutomaticProfileResetter::SetDelegateForTesting( |
| 308 AutomaticProfileResetterDelegate* delegate) { | 438 scoped_ptr<AutomaticProfileResetterDelegate> delegate) { |
| 309 delegate_.reset(delegate); | 439 delegate_ = delegate.Pass(); |
| 440 } |
| 441 |
| 442 void AutomaticProfileResetter::SetTaskRunnerForWaitingForTesting( |
| 443 const scoped_refptr<base::TaskRunner>& task_runner) { |
| 444 task_runner_for_waiting_ = task_runner; |
| 310 } | 445 } |
| 311 | 446 |
| 312 void AutomaticProfileResetter::Shutdown() { | 447 void AutomaticProfileResetter::Shutdown() { |
| 313 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 448 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 314 | 449 |
| 315 state_ = STATE_DISABLED; | 450 state_ = STATE_DISABLED; |
| 316 delegate_.reset(); | 451 delegate_.reset(); |
| 317 weak_ptr_factory_.InvalidateWeakPtrs(); | 452 weak_ptr_factory_.InvalidateWeakPtrs(); |
| 318 } | 453 } |
| OLD | NEW |