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

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: 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 "chrome/browser/browser_process.h"
18 #include "chrome/browser/profile_resetter/automatic_profile_resetter_delegate.h"
16 #include "chrome/browser/profile_resetter/jtl_interpreter.h" 19 #include "chrome/browser/profile_resetter/jtl_interpreter.h"
17 #include "chrome/browser/profiles/profile.h" 20 #include "chrome/browser/profiles/profile.h"
18 #include "content/public/browser/browser_thread.h" 21 #include "content/public/browser/browser_thread.h"
19 #include "grit/browser_resources.h" 22 #include "grit/browser_resources.h"
20 #include "ui/base/resource/resource_bundle.h" 23 #include "ui/base/resource/resource_bundle.h"
21 24
22 namespace { 25 namespace {
23 26
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. 27 // Name constants for the field trial behind which we enable this feature.
37 const char kAutomaticProfileResetStudyName[] = "AutomaticProfileReset"; 28 const char kAutomaticProfileResetStudyName[] = "AutomaticProfileReset";
38 const char kAutomaticProfileResetStudyDryRunGroupName[] = "DryRun"; 29 const char kAutomaticProfileResetStudyDryRunGroupName[] = "DryRun";
39 const char kAutomaticProfileResetStudyEnabledGroupName[] = "Enabled"; 30 const char kAutomaticProfileResetStudyEnabledGroupName[] = "Enabled";
40 31
41 // Keys used in the input dictionary of the program. 32 // Keys used in the input dictionary of the program.
42 // TODO(engedy): Add these here on an as-needed basis. 33 const char kUserPreferencesKey[] = "preferences";
34 const char kUserPreferencesIsUserControlledKey[] = "preferences_iuc";
35 const char kLocalStateKey[] = "local_state";
36 const char kLocalStateIsUserControlledKey[] = "local_state_iuc";
37 const char kSearchProvidersKey[] = "search_providers";
38 const char kDefaultSearchProviderKey[] = "default_search_provider";
39 const char kDefaultSearchProviderIsUserControlledKey[] =
40 "default_search_provider_iuc";
43 41
44 // Keys used in the output dictionary of the program. 42 // Keys used in the output dictionary of the program.
45 const char kHadPromptedAlreadyKey[] = "had_prompted_already"; 43 const char kHadPromptedAlreadyKey[] = "had_prompted_already";
46 const char kSatisfiedCriteriaMaskKeys[][29] = {"satisfied_criteria_mask_bit1", 44 const char kSatisfiedCriteriaMaskKeys[][29] = {"satisfied_criteria_mask_bit1",
47 "satisfied_criteria_mask_bit2"}; 45 "satisfied_criteria_mask_bit2"};
48 const char kCombinedStatusMaskKeys[][26] = { 46 const char kCombinedStatusMaskKeys[][26] = {
49 "combined_status_mask_bit1", "combined_status_mask_bit2", 47 "combined_status_mask_bit1", "combined_status_mask_bit2",
50 "combined_status_mask_bit3", "combined_status_mask_bit4"}; 48 "combined_status_mask_bit3", "combined_status_mask_bit4"};
51 49
52 // Keys used in both the input and output dictionary of the program. 50 // Keys used in both the input and output dictionary of the program.
53 const char kMementoValueInPrefsKey[] = "memento_value_in_prefs"; 51 const char kMementoValueInPrefsKey[] = "memento_value_in_prefs";
54 const char kMementoValueInLocalStateKey[] = "memento_value_in_local_state"; 52 const char kMementoValueInLocalStateKey[] = "memento_value_in_local_state";
55 const char kMementoValueInFileKey[] = "memento_value_in_file"; 53 const char kMementoValueInFileKey[] = "memento_value_in_file";
56 54
57 COMPILE_ASSERT( 55 // 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 56
91 // Enumeration of the possible outcomes of showing the profile reset prompt. 57 // Enumeration of the possible outcomes of showing the profile reset prompt.
92 enum PromptResult { 58 enum PromptResult {
93 // Prompt was not shown because only a dry-run was performed. 59 // Prompt was not shown because only a dry-run was performed.
94 PROMPT_NOT_SHOWN, 60 PROMPT_NOT_SHOWN,
95 PROMPT_ACTION_RESET, 61 PROMPT_ACTION_RESET,
96 PROMPT_ACTION_NO_RESET, 62 PROMPT_ACTION_NO_RESET,
97 PROMPT_DISMISSED, 63 PROMPT_DISMISSED,
98 // Prompt was still shown (not dismissed by the user) when Chrome was closed. 64 // Prompt was still shown (not dismissed by the user) when Chrome was closed.
99 PROMPT_IGNORED, 65 PROMPT_IGNORED,
100 PROMPT_RESULT_MAX 66 PROMPT_RESULT_MAX
101 }; 67 };
102 68
69 // Deep-copies all preferences in |source| to a sub-tree named |value_tree_key|
70 // in |target_dictionary|, with path expansion, and also creates an isomorphic
71 // sub-tree under the key |is_user_controlled_tree_key| that contains only
72 // Boolean values, indicating whether or not the corresponding preferences are
73 // coming from the 'user' PrefStore.
74 void BuildSubTreesFromPreferences(const PrefService* source,
75 base::DictionaryValue* target_dictionary,
76 const char* value_tree_key,
77 const char* is_user_controlled_tree_key) {
78 scoped_ptr<base::DictionaryValue> pref_name_to_value_map(
79 source->GetPreferenceValuesWithoutPathExpansion());
80 base::DictionaryValue* value_tree = new base::DictionaryValue;
81 base::DictionaryValue* is_user_controlled_tree = new base::DictionaryValue;
82 for (base::DictionaryValue::Iterator it(*pref_name_to_value_map);
83 !it.IsAtEnd();
84 it.Advance()) {
85 value_tree->Set(it.key(), it.value().DeepCopy());
battre 2013/10/11 15:05:33 Should this and the one in line 88 be SetWithoutPa
engedy 2013/10/11 16:42:16 Avoided the double-copy as we discussed.
86 const PrefService::Preference* pref =
87 source->FindPreference(it.key().c_str());
88 is_user_controlled_tree->Set(
89 it.key(), new base::FundamentalValue(pref->IsUserControlled()));
90 }
91 target_dictionary->Set(value_tree_key, value_tree);
92 target_dictionary->Set(is_user_controlled_tree_key, is_user_controlled_tree);
93 }
94
103 } // namespace 95 } // namespace
104 96
105 // AutomaticProfileResetter::EvaluationResults ------------------------------- 97 // AutomaticProfileResetter::EvaluationResults -------------------------------
106 98
107 // Encapsulates the output values extracted from the evaluator program. 99 // Encapsulates the output values extracted from the evaluator program.
108 struct AutomaticProfileResetter::EvaluationResults { 100 struct AutomaticProfileResetter::EvaluationResults {
109 EvaluationResults() 101 EvaluationResults()
110 : had_prompted_already(false), 102 : had_prompted_already(false),
111 satisfied_criteria_mask(0), 103 satisfied_criteria_mask(0),
112 combined_status_mask(0) {} 104 combined_status_mask(0) {}
113 105
114 std::string memento_value_in_prefs; 106 std::string memento_value_in_prefs;
115 std::string memento_value_in_local_state; 107 std::string memento_value_in_local_state;
116 std::string memento_value_in_file; 108 std::string memento_value_in_file;
117 109
118 bool had_prompted_already; 110 bool had_prompted_already;
119 uint32 satisfied_criteria_mask; 111 uint32 satisfied_criteria_mask;
120 uint32 combined_status_mask; 112 uint32 combined_status_mask;
121 }; 113 };
122 114
123 // AutomaticProfileResetter -------------------------------------------------- 115 // AutomaticProfileResetter --------------------------------------------------
124 116
117 const size_t AutomaticProfileResetter::kSatisfiedCriteriaMaskBits = 2;
118 const uint32 AutomaticProfileResetter::kSatisfiedCriteriaMaskMaximumValue =
119 (1 << AutomaticProfileResetter::kSatisfiedCriteriaMaskBits);
120
121 const size_t AutomaticProfileResetter::kCombinedStatusMaskBits = 4;
122 const uint32 AutomaticProfileResetter::kCombinedStatusMaskMaximumValue =
123 (1 << AutomaticProfileResetter::kCombinedStatusMaskBits);
124
125 COMPILE_ASSERT(arraysize(kSatisfiedCriteriaMaskKeys) ==
126 ::AutomaticProfileResetter::kSatisfiedCriteriaMaskBits,
127 satisfied_criteria_mask_bits_mismatch);
128 COMPILE_ASSERT(arraysize(kCombinedStatusMaskKeys) ==
129 ::AutomaticProfileResetter::kCombinedStatusMaskBits,
130 combined_status_mask_bits_mismatch);
131
125 AutomaticProfileResetter::AutomaticProfileResetter(Profile* profile) 132 AutomaticProfileResetter::AutomaticProfileResetter(Profile* profile)
126 : profile_(profile), 133 : profile_(profile),
127 state_(STATE_UNINITIALIZED), 134 state_(STATE_UNINITIALIZED),
128 memento_in_prefs_(profile_), 135 memento_in_prefs_(profile_),
129 memento_in_local_state_(profile_), 136 memento_in_local_state_(profile_),
130 memento_in_file_(profile_), 137 memento_in_file_(profile_),
131 weak_ptr_factory_(this) { 138 weak_ptr_factory_(this) {
132 DCHECK(profile_); 139 DCHECK(profile_);
140 MaybeInitialize();
133 } 141 }
134 142
135 AutomaticProfileResetter::~AutomaticProfileResetter() {} 143 AutomaticProfileResetter::~AutomaticProfileResetter() {}
136 144
137 void AutomaticProfileResetter::Initialize() { 145 void AutomaticProfileResetter::MaybeInitialize() {
138 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 146 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
139 DCHECK_EQ(state_, STATE_UNINITIALIZED); 147 DCHECK_EQ(state_, STATE_UNINITIALIZED);
140 148
141 if (ShouldPerformDryRun() || ShouldPerformLiveRun()) { 149 if (ShouldPerformDryRun() || ShouldPerformLiveRun()) {
142 ui::ResourceBundle& resources(ui::ResourceBundle::GetSharedInstance()); 150 ui::ResourceBundle& resources(ui::ResourceBundle::GetSharedInstance());
143 if (ShouldPerformLiveRun()) { 151 if (ShouldPerformLiveRun()) {
144 program_ = 152 program_ =
145 resources.GetRawDataResource(IDR_AUTOMATIC_PROFILE_RESET_RULES); 153 resources.GetRawDataResource(IDR_AUTOMATIC_PROFILE_RESET_RULES);
146 hash_seed_ = 154 hash_seed_ =
147 resources.GetRawDataResource(IDR_AUTOMATIC_PROFILE_RESET_HASH_SEED); 155 resources.GetRawDataResource(IDR_AUTOMATIC_PROFILE_RESET_HASH_SEED);
148 } else { // ShouldPerformDryRun() 156 } else { // ShouldPerformDryRun()
149 program_ = 157 program_ =
150 resources.GetRawDataResource(IDR_AUTOMATIC_PROFILE_RESET_RULES_DRY); 158 resources.GetRawDataResource(IDR_AUTOMATIC_PROFILE_RESET_RULES_DRY);
151 hash_seed_ = resources.GetRawDataResource( 159 hash_seed_ = resources.GetRawDataResource(
152 IDR_AUTOMATIC_PROFILE_RESET_HASH_SEED_DRY); 160 IDR_AUTOMATIC_PROFILE_RESET_HASH_SEED_DRY);
153 } 161 }
154 delegate_.reset(new AutomaticProfileResetterDelegateImpl()); 162 delegate_.reset(new AutomaticProfileResetterDelegateImpl(profile_));
155 163 state_ = STATE_INITIALIZED;
156 state_ = STATE_READY;
157
158 content::BrowserThread::PostTask(
159 content::BrowserThread::UI,
160 FROM_HERE,
161 base::Bind(&AutomaticProfileResetter::BeginEvaluationFlow,
162 weak_ptr_factory_.GetWeakPtr()));
163 } else { 164 } else {
164 state_ = STATE_DISABLED; 165 state_ = STATE_DISABLED;
165 } 166 }
166 } 167 }
167 168
169 void AutomaticProfileResetter::MaybeActivate() {
170 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
171 DCHECK(state_ == STATE_INITIALIZED || state_ == STATE_DISABLED);
172
173 if (state_ == STATE_INITIALIZED) {
174 if (!program_.empty()) {
175 state_ = STATE_WAITING_ON_SERVICES;
176 delegate_->WaitOnTemplateURLService(
177 base::Bind(&AutomaticProfileResetter::OnTemplateURLServiceBecameReady,
178 weak_ptr_factory_.GetWeakPtr()));
179 delegate_->LoadTemplateURLServiceIfNeeded();
180 } else {
181 // Terminate early if there is no program included (nor set by tests).
182 state_ = STATE_DISABLED;
183 }
184 }
185 }
186
168 bool AutomaticProfileResetter::ShouldPerformDryRun() const { 187 bool AutomaticProfileResetter::ShouldPerformDryRun() const {
169 return base::FieldTrialList::FindFullName(kAutomaticProfileResetStudyName) == 188 return base::FieldTrialList::FindFullName(kAutomaticProfileResetStudyName) ==
170 kAutomaticProfileResetStudyDryRunGroupName; 189 kAutomaticProfileResetStudyDryRunGroupName;
171 } 190 }
172 191
173 bool AutomaticProfileResetter::ShouldPerformLiveRun() const { 192 bool AutomaticProfileResetter::ShouldPerformLiveRun() const {
174 return base::FieldTrialList::FindFullName(kAutomaticProfileResetStudyName) == 193 return base::FieldTrialList::FindFullName(kAutomaticProfileResetStudyName) ==
175 kAutomaticProfileResetStudyEnabledGroupName; 194 kAutomaticProfileResetStudyEnabledGroupName;
176 } 195 }
177 196
197 void AutomaticProfileResetter::OnTemplateURLServiceBecameReady() {
198 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
199 DCHECK_EQ(state_, STATE_WAITING_ON_SERVICES);
battre 2013/10/11 15:05:33 nit: please swap order of parameters.
engedy 2013/10/11 16:42:16 As discussed, the original order actually looked s
200
201 state_ = STATE_READY;
202 content::BrowserThread::PostTask(
203 content::BrowserThread::UI,
204 FROM_HERE,
205 base::Bind(&AutomaticProfileResetter::BeginEvaluationFlow,
206 weak_ptr_factory_.GetWeakPtr()));
207 }
208
178 void AutomaticProfileResetter::BeginEvaluationFlow() { 209 void AutomaticProfileResetter::BeginEvaluationFlow() {
179 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 210 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
180 DCHECK_EQ(state_, STATE_READY); 211 DCHECK_EQ(state_, STATE_READY);
battre 2013/10/11 15:05:33 same here.
engedy 2013/10/11 16:42:16 Same as above.
212 DCHECK(!program_.empty());
181 213
182 if (!program_.empty()) { 214 state_ = STATE_WORKING;
183 state_ = STATE_WORKING; 215 memento_in_file_.ReadValue(
184 memento_in_file_.ReadValue( 216 base::Bind(&AutomaticProfileResetter::ContinueWithEvaluationFlow,
185 base::Bind(&AutomaticProfileResetter::ContinueWithEvaluationFlow, 217 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 } 218 }
192 219
193 scoped_ptr<base::DictionaryValue> 220 scoped_ptr<base::DictionaryValue>
194 AutomaticProfileResetter::BuildEvaluatorProgramInput( 221 AutomaticProfileResetter::BuildEvaluatorProgramInput(
195 const std::string& memento_value_in_file) { 222 const std::string& memento_value_in_file) {
196 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 223 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
197 // TODO(engedy): Add any additional state here that is needed by the program. 224
198 scoped_ptr<base::DictionaryValue> input(new base::DictionaryValue); 225 scoped_ptr<base::DictionaryValue> input(new base::DictionaryValue);
226
227 // Include memento values (or empty strings in case mementos are not there).
199 input->SetString(kMementoValueInPrefsKey, memento_in_prefs_.ReadValue()); 228 input->SetString(kMementoValueInPrefsKey, memento_in_prefs_.ReadValue());
200 input->SetString(kMementoValueInLocalStateKey, 229 input->SetString(kMementoValueInLocalStateKey,
201 memento_in_local_state_.ReadValue()); 230 memento_in_local_state_.ReadValue());
202 input->SetString(kMementoValueInFileKey, memento_value_in_file); 231 input->SetString(kMementoValueInFileKey, memento_value_in_file);
232
233 // Include all user (i.e. profile-specific) preferences, along with
234 // information about whether the value is coming from the 'user' PrefStore.
235 PrefService* prefs = profile_->GetPrefs();
236 DCHECK(prefs);
237 BuildSubTreesFromPreferences(prefs,
238 input.get(),
239 kUserPreferencesKey,
240 kUserPreferencesIsUserControlledKey);
241
242 // Include all local state (i.e. shared) preferences, along with information
243 // about whether the value is coming from the 'user' PrefStore.
244 PrefService* local_state = g_browser_process->local_state();
245 DCHECK(local_state);
246 BuildSubTreesFromPreferences(
247 local_state, input.get(), kLocalStateKey, kLocalStateIsUserControlledKey);
248
249 // Include all information related to search engines.
250 base::DictionaryValue* default_search_provider_details =
251 delegate_->GetDefaultSearchProviderDetails();
252 if (default_search_provider_details)
253 input->Set(kDefaultSearchProviderKey, default_search_provider_details);
254
255 base::ListValue* search_providers_details =
256 delegate_->GetPrepopulatedSearchProvidersDetails();
257 if (search_providers_details)
258 input->Set(kSearchProvidersKey, search_providers_details);
259
260 input->SetBoolean(kDefaultSearchProviderIsUserControlledKey,
261 !delegate_->IsDefaultSearchProviderManaged());
262
203 return input.Pass(); 263 return input.Pass();
204 } 264 }
205 265
206 void AutomaticProfileResetter::ContinueWithEvaluationFlow( 266 void AutomaticProfileResetter::ContinueWithEvaluationFlow(
207 const std::string& memento_value_in_file) { 267 const std::string& memento_value_in_file) {
208 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 268 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
209 DCHECK_EQ(state_, STATE_WORKING); 269 DCHECK_EQ(state_, STATE_WORKING);
210 PrefService* prefs = profile_->GetPrefs(); 270 PrefService* prefs = profile_->GetPrefs();
211 DCHECK(prefs); 271 DCHECK(prefs);
212 272
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
309 delegate_.reset(delegate); 369 delegate_.reset(delegate);
310 } 370 }
311 371
312 void AutomaticProfileResetter::Shutdown() { 372 void AutomaticProfileResetter::Shutdown() {
313 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 373 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
314 374
315 state_ = STATE_DISABLED; 375 state_ = STATE_DISABLED;
316 delegate_.reset(); 376 delegate_.reset();
317 weak_ptr_factory_.InvalidateWeakPtrs(); 377 weak_ptr_factory_.InvalidateWeakPtrs();
318 } 378 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698