OLD | NEW |
| (Empty) |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #ifndef CHROME_BROWSER_PROFILE_RESETTER_AUTOMATIC_PROFILE_RESETTER_H_ | |
6 #define CHROME_BROWSER_PROFILE_RESETTER_AUTOMATIC_PROFILE_RESETTER_H_ | |
7 | |
8 #include <string> | |
9 | |
10 #include "base/basictypes.h" | |
11 #include "base/memory/ref_counted.h" | |
12 #include "base/memory/scoped_ptr.h" | |
13 #include "base/memory/weak_ptr.h" | |
14 #include "base/strings/string_piece.h" | |
15 #include "base/task_runner.h" | |
16 #include "chrome/browser/profile_resetter/automatic_profile_resetter_mementos.h" | |
17 #include "components/keyed_service/core/keyed_service.h" | |
18 | |
19 class AutomaticProfileResetterDelegate; | |
20 class Profile; | |
21 | |
22 namespace base { | |
23 class DictionaryValue; | |
24 class ListValue; | |
25 } | |
26 | |
27 // This service is responsible for evaluating whether the criteria for showing | |
28 // the one-time profile reset prompt are satisfied, and for potentially | |
29 // triggering the prompt. To ensure that the prompt only appears at most once | |
30 // for any given profile, a "memento" that the prompt has appeared is written to | |
31 // the profile on disk; see automatic_profile_resetter_mementos.h for details. | |
32 // The service is created automatically with the Profile and is activated right | |
33 // away by its factory. To avoid delaying start-up, however, it will only start | |
34 // working after a short delay. | |
35 // All methods in this class shall be called on the UI thread, except when noted | |
36 // otherwise. | |
37 class AutomaticProfileResetter : public KeyedService { | |
38 public: | |
39 // Enumeration listing the possible outcomes of triggering the profile reset | |
40 // prompt. | |
41 enum PromptResult { | |
42 // The reset prompt was not triggered because only a dry-run was performed, | |
43 // or because it was not supported on the current platform. | |
44 PROMPT_NOT_TRIGGERED, | |
45 // The reset bubble actually got shown. In contrast to the wrench menu item | |
46 // that can always be shown, the bubble might be delayed or might never be | |
47 // shown if another bubble was shown at the time of triggering the prompt. | |
48 // This enumeration value is usually recorded in conjunction with another | |
49 // PromptResult, the absence of which indicates that the prompt was ignored. | |
50 PROMPT_SHOWN_BUBBLE, | |
51 // The user selected "Reset" or "No, thanks" (respectively) directly from | |
52 // within the bubble. | |
53 PROMPT_ACTION_RESET, | |
54 PROMPT_ACTION_NO_RESET, | |
55 // The reset bubble was shown, then dismissed without taking definitive | |
56 // action. Then, however, the user initiated or refrained from doing a reset | |
57 // (respectively) from the conventional, WebUI-based reset dialog. | |
58 PROMPT_FOLLOWED_BY_WEBUI_RESET, | |
59 PROMPT_FOLLOWED_BY_WEBUI_NO_RESET, | |
60 // The reset bubble was suppressed (not shown) because another bubble was | |
61 // already being shown at the time. Regardless, however, the user initiated | |
62 // or refrained from doing a reset (respectively) from the conventional, | |
63 // WebUI-based reset dialog. | |
64 PROMPT_NOT_SHOWN_BUBBLE_BUT_HAD_WEBUI_RESET, | |
65 PROMPT_NOT_SHOWN_BUBBLE_BUT_HAD_WEBUI_NO_RESET, | |
66 PROMPT_RESULT_MAX | |
67 }; | |
68 | |
69 explicit AutomaticProfileResetter(Profile* profile); | |
70 virtual ~AutomaticProfileResetter(); | |
71 | |
72 // Initializes the service if it is enabled in the field trial. Otherwise, | |
73 // skips the initialization steps, and also permanently disables the service. | |
74 // Called by AutomaticProfileResetterFactory. | |
75 void Initialize(); | |
76 | |
77 // Fires up the service by unleashing the asynchronous evaluation flow, unless | |
78 // the service has been already disabled in Initialize() or there is no | |
79 // |program_| to run (in which case the service also gets disabled). | |
80 // Called by the AutomaticProfileResetterFactory. | |
81 void Activate(); | |
82 | |
83 // Called in case the user chooses to reset their profile settings from inside | |
84 // the reset bubble. Will trigger the reset, optionally |send_feedback|, and | |
85 // conclude the reset prompt flow. | |
86 void TriggerProfileReset(bool send_feedback); | |
87 | |
88 // Called in case the user chooses from inside the reset bubble that they do | |
89 // not want to reset their profile settings. Will conclude the reset prompt | |
90 // flow without setting off a reset. | |
91 void SkipProfileReset(); | |
92 | |
93 // Returns whether or not the profile reset prompt flow is currently active, | |
94 // that is, we have triggered the prompt and are waiting for the user to take | |
95 // definitive action (and we are not yet performing a reset). | |
96 bool IsResetPromptFlowActive() const; | |
97 | |
98 // Returns whether or not the profile reset banner should be shown on the | |
99 // WebUI-based settings page. | |
100 bool ShouldShowResetBanner() const; | |
101 | |
102 // Called to give notice that the reset bubble has actually been shown. | |
103 void NotifyDidShowResetBubble(); | |
104 | |
105 // Called to give notice that the conventional, WebUI-based settings reset | |
106 // dialog has been opened. This will dismiss the menu item in the wrench menu. | |
107 // This should always be followed by a corresponding call to | |
108 // NotifyDidCloseWebUIResetDialog(). | |
109 void NotifyDidOpenWebUIResetDialog(); | |
110 | |
111 // Called to give notice that the conventional, WebUI-based settings reset | |
112 // dialog has been closed, with |performed_reset| indicating whether or not a | |
113 // reset was requested. This is required so that we can record the appropriate | |
114 // PromptResult, dismiss the prompt, and conclude the reset prompt flow early | |
115 // without setting off any resets in the future. | |
116 void NotifyDidCloseWebUIResetDialog(bool performed_reset); | |
117 | |
118 // Called to give notice that reset banner has been dismissed as a result of | |
119 // user action on the WebUI-based settings page itself. | |
120 void NotifyDidCloseWebUIResetBanner(); | |
121 | |
122 base::WeakPtr<AutomaticProfileResetter> AsWeakPtr() { | |
123 return weak_ptr_factory_.GetWeakPtr(); | |
124 } | |
125 | |
126 // Should be called before Activate(). | |
127 void SetProgramForTesting(const std::string& program); | |
128 | |
129 // Should be called before Activate(). | |
130 void SetHashSeedForTesting(const std::string& hash_seed); | |
131 | |
132 // Should be called before Activate(). | |
133 void SetDelegateForTesting( | |
134 scoped_ptr<AutomaticProfileResetterDelegate> delegate); | |
135 | |
136 // Should be called before Activate(). Sets the task runner to be used to post | |
137 // task |PrepareEvaluationFlow| in a delayed manner. | |
138 void SetTaskRunnerForWaitingForTesting( | |
139 const scoped_refptr<base::TaskRunner>& task_runner); | |
140 | |
141 // KeyedService: | |
142 virtual void Shutdown() OVERRIDE; | |
143 | |
144 private: | |
145 class InputBuilder; | |
146 struct EvaluationResults; | |
147 | |
148 enum State { | |
149 STATE_UNINITIALIZED, | |
150 STATE_INITIALIZED, | |
151 STATE_DISABLED, | |
152 STATE_WAITING_ON_DEPENDENCIES, | |
153 STATE_READY, | |
154 STATE_EVALUATING_CONDITIONS, | |
155 // The reset prompt has been triggered; but the reset bubble has not yet | |
156 // been shown. | |
157 STATE_HAS_TRIGGERED_PROMPT, | |
158 // The reset prompt has been triggered; the reset bubble has been shown, and | |
159 // potentially already dismissed by the user. | |
160 STATE_HAS_SHOWN_BUBBLE, | |
161 STATE_PERFORMING_RESET, | |
162 STATE_DONE | |
163 }; | |
164 | |
165 // Prepares the asynchronous evaluation flow by requesting services that it | |
166 // depends on to make themselves ready. | |
167 void PrepareEvaluationFlow(); | |
168 | |
169 // Called back by |resetter_delegate_| when the template URL service is ready. | |
170 void OnTemplateURLServiceIsLoaded(); | |
171 | |
172 // Called back by |resetter_delegate_| when the loaded modules have been | |
173 // enumerated. | |
174 void OnLoadedModulesAreEnumerated(); | |
175 | |
176 // Invoked by the above two methods. Kicks off the actual evaluation flow. | |
177 void OnDependencyIsReady(); | |
178 | |
179 // Begins the asynchronous evaluation flow, which will assess whether the | |
180 // criteria for showing the reset prompt are met, whether we have already | |
181 // shown the prompt; and, in the end, will potentially trigger the prompt. | |
182 void BeginEvaluationFlow(); | |
183 | |
184 // Called by InputBuilder once it has finished assembling the |program_input|, | |
185 // and will continue with the evaluation flow by triggering the evaluator | |
186 // program on the worker thread. | |
187 void ContinueWithEvaluationFlow( | |
188 scoped_ptr<base::DictionaryValue> program_input); | |
189 | |
190 // Performs the bulk of the work. Invokes the JTL interpreter to run the | |
191 // |program| that will evaluate whether the conditions are met for showing the | |
192 // reset prompt. The program will make this decision based on the state | |
193 // information contained in |input| in the form of key-value pairs. The | |
194 // program will only see hashed keys and values that are produced using | |
195 // |hash_seed| as a key. | |
196 static scoped_ptr<EvaluationResults> EvaluateConditionsOnWorkerPoolThread( | |
197 const std::string& hash_seed, | |
198 const std::string& program, | |
199 scoped_ptr<base::DictionaryValue> program_input); | |
200 | |
201 // Reports the given metrics through UMA. Virtual, so it can be mocked out in | |
202 // tests to verify that the correct value are being reported. | |
203 virtual void ReportStatistics(uint32 satisfied_criteria_mask, | |
204 uint32 combined_status_mask); | |
205 | |
206 // Called back when EvaluateConditionsOnWorkerPoolThread completes executing | |
207 // the program with |results|. Finishes the evaluation flow, and, based on the | |
208 // result, potentially initiates the reset prompt flow. | |
209 void FinishEvaluationFlow(scoped_ptr<EvaluationResults> results); | |
210 | |
211 // Begins the reset prompt flow by triggering the reset prompt, which consists | |
212 // of two parts: (1.) the profile reset (pop-up) bubble, and (2.) a menu item | |
213 // in the wrench menu (provided by a GlobalError). | |
214 // The flow lasts until we receive a clear indication from the user about | |
215 // whether or not they wish to reset their settings. This indication can come | |
216 // in a variety of flavors: | |
217 // * taking definitive action (i.e. selecting either "Reset" or "No, thanks") | |
218 // in the pop-up reset bubble itself, | |
219 // * dismissing the bubble, but then selecting the wrench menu item, which | |
220 // takes them to the WebUI reset dialog in chrome://settings, and then the | |
221 // user can make their choice there, | |
222 // * the user going to the WebUI reset dialog by themself. | |
223 // For the most part, the conclusion of the reset flow coincides with when the | |
224 // reset prompt is dismissed, with the one exception being that the prompt is | |
225 // closed as soon as the WebUI reset dialog is opened, we do not wait until | |
226 // the user actually makes a choice in that dialog. | |
227 void BeginResetPromptFlow(); | |
228 | |
229 // Called back by the ProfileResetter once resetting the profile settings has | |
230 // been completed, when requested by the user from inside the reset bubble. | |
231 // Will dismiss the prompt and conclude the reset prompt flow. | |
232 void OnProfileSettingsResetCompleted(); | |
233 | |
234 // Reports the result of triggering the prompt through UMA. Virtual, so it can | |
235 // be mocked out in tests to verify that the correct value is being reported. | |
236 virtual void ReportPromptResult(PromptResult result); | |
237 | |
238 // Writes the memento values returned by the evaluation program to disk, and | |
239 // then destroys |evaluation_results_|. | |
240 void PersistMementos(); | |
241 | |
242 // Concludes the reset prompt flow. | |
243 void FinishResetPromptFlow(); | |
244 | |
245 Profile* profile_; | |
246 | |
247 State state_; | |
248 bool enumeration_of_loaded_modules_ready_; | |
249 bool template_url_service_ready_; | |
250 bool has_already_dismissed_prompt_; | |
251 | |
252 scoped_ptr<InputBuilder> input_builder_; | |
253 std::string hash_seed_; | |
254 std::string program_; | |
255 | |
256 scoped_ptr<EvaluationResults> evaluation_results_; | |
257 | |
258 bool should_show_reset_banner_; | |
259 | |
260 scoped_ptr<AutomaticProfileResetterDelegate> delegate_; | |
261 scoped_refptr<base::TaskRunner> task_runner_for_waiting_; | |
262 | |
263 base::WeakPtrFactory<AutomaticProfileResetter> weak_ptr_factory_; | |
264 | |
265 DISALLOW_COPY_AND_ASSIGN(AutomaticProfileResetter); | |
266 }; | |
267 | |
268 #endif // CHROME_BROWSER_PROFILE_RESETTER_AUTOMATIC_PROFILE_RESETTER_H_ | |
OLD | NEW |