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