Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(66)

Side by Side Diff: chrome/browser/profile_resetter/automatic_profile_resetter.cc

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

Powered by Google App Engine
This is Rietveld 408576698