QUIC - cleanup changes to sync chromium tree with internal source.
[chromium-blink-merge.git] / chrome / browser / profile_resetter / automatic_profile_resetter.h
blob0e43a1b53677db0a4de1d418e6ec74bfa4775420
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.
5 #ifndef CHROME_BROWSER_PROFILE_RESETTER_AUTOMATIC_PROFILE_RESETTER_H_
6 #define CHROME_BROWSER_PROFILE_RESETTER_AUTOMATIC_PROFILE_RESETTER_H_
8 #include <string>
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"
19 class AutomaticProfileResetterDelegate;
20 class Profile;
22 namespace base {
23 class DictionaryValue;
24 class ListValue;
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
69 explicit AutomaticProfileResetter(Profile* profile);
70 ~AutomaticProfileResetter() override;
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();
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();
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);
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();
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;
98 // Returns whether or not the profile reset banner should be shown on the
99 // WebUI-based settings page.
100 bool ShouldShowResetBanner() const;
102 // Called to give notice that the reset bubble has actually been shown.
103 void NotifyDidShowResetBubble();
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();
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);
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();
122 base::WeakPtr<AutomaticProfileResetter> AsWeakPtr() {
123 return weak_ptr_factory_.GetWeakPtr();
126 // Should be called before Activate().
127 void SetProgramForTesting(const std::string& program);
129 // Should be called before Activate().
130 void SetHashSeedForTesting(const std::string& hash_seed);
132 // Should be called before Activate().
133 void SetDelegateForTesting(
134 scoped_ptr<AutomaticProfileResetterDelegate> delegate);
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);
141 // KeyedService:
142 void Shutdown() override;
144 private:
145 class InputBuilder;
146 struct EvaluationResults;
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
165 // Prepares the asynchronous evaluation flow by requesting services that it
166 // depends on to make themselves ready.
167 void PrepareEvaluationFlow();
169 // Called back by |resetter_delegate_| when the template URL service is ready.
170 void OnTemplateURLServiceIsLoaded();
172 // Called back by |resetter_delegate_| when the loaded modules have been
173 // enumerated.
174 void OnLoadedModulesAreEnumerated();
176 // Invoked by the above two methods. Kicks off the actual evaluation flow.
177 void OnDependencyIsReady();
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();
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);
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);
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);
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);
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();
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();
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);
238 // Writes the memento values returned by the evaluation program to disk, and
239 // then destroys |evaluation_results_|.
240 void PersistMementos();
242 // Concludes the reset prompt flow.
243 void FinishResetPromptFlow();
245 Profile* profile_;
247 State state_;
248 bool enumeration_of_loaded_modules_ready_;
249 bool template_url_service_ready_;
250 bool has_already_dismissed_prompt_;
252 scoped_ptr<InputBuilder> input_builder_;
253 std::string hash_seed_;
254 std::string program_;
256 scoped_ptr<EvaluationResults> evaluation_results_;
258 bool should_show_reset_banner_;
260 scoped_ptr<AutomaticProfileResetterDelegate> delegate_;
261 scoped_refptr<base::TaskRunner> task_runner_for_waiting_;
263 base::WeakPtrFactory<AutomaticProfileResetter> weak_ptr_factory_;
265 DISALLOW_COPY_AND_ASSIGN(AutomaticProfileResetter);
268 #endif // CHROME_BROWSER_PROFILE_RESETTER_AUTOMATIC_PROFILE_RESETTER_H_