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

Side by Side Diff: chrome/browser/ui/webui/sync_promo_handler2.cc

Issue 8895023: Options2: Pull the trigger. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: DIAF. Created 9 years 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
(Empty)
1 // Copyright (c) 2011 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 #include "chrome/browser/ui/webui/sync_promo_handler2.h"
6
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/metrics/histogram.h"
10 #include "base/time.h"
11 #include "chrome/browser/prefs/pref_service.h"
12 #include "chrome/browser/profiles/profile.h"
13 #include "chrome/browser/sync/profile_sync_service.h"
14 #include "chrome/browser/sync/sync_setup_flow.h"
15 #include "chrome/browser/tabs/tab_strip_model.h"
16 #include "chrome/browser/ui/browser.h"
17 #include "chrome/browser/ui/browser_list.h"
18 #include "chrome/browser/ui/webui/sync_promo_trial.h"
19 #include "chrome/browser/ui/webui/sync_promo_ui.h"
20 #include "chrome/common/chrome_notification_types.h"
21 #include "chrome/common/extensions/extension_constants.h"
22 #include "chrome/common/pref_names.h"
23 #include "chrome/common/url_constants.h"
24 #include "content/browser/tab_contents/tab_contents.h"
25 #include "content/public/browser/notification_details.h"
26 #include "content/public/browser/notification_service.h"
27
28 namespace {
29
30 // User actions on the sync promo (aka "Sign in to Chrome").
31 enum SyncPromoUserFlowActionEnums {
32 SYNC_PROMO_VIEWED,
33 SYNC_PROMO_LEARN_MORE_CLICKED,
34 SYNC_PROMO_ACCOUNT_HELP_CLICKED,
35 SYNC_PROMO_CREATE_ACCOUNT_CLICKED,
36 SYNC_PROMO_SKIP_CLICKED,
37 SYNC_PROMO_SIGN_IN_ATTEMPTED,
38 SYNC_PROMO_SIGNED_IN_SUCCESSFULLY,
39 SYNC_PROMO_ADVANCED_CLICKED,
40 SYNC_PROMO_ENCRYPTION_HELP_CLICKED,
41 SYNC_PROMO_CANCELLED_AFTER_SIGN_IN,
42 SYNC_PROMO_CONFIRMED_AFTER_SIGN_IN,
43 SYNC_PROMO_CLOSED_TAB,
44 SYNC_PROMO_CLOSED_WINDOW,
45 SYNC_PROMO_LEFT_DURING_THROBBER,
46 SYNC_PROMO_BUCKET_BOUNDARY,
47 SYNC_PROMO_FIRST_VALID_JS_ACTION = SYNC_PROMO_LEARN_MORE_CLICKED,
48 SYNC_PROMO_LAST_VALID_JS_ACTION = SYNC_PROMO_CONFIRMED_AFTER_SIGN_IN,
49 };
50
51 // This was added because of the need to change the existing UMA enum for the
52 // sync promo mid-flight. Ideally these values would be contiguous, but the
53 // real world is not always ideal.
54 static bool IsValidUserFlowAction(int action) {
55 return (action >= SYNC_PROMO_FIRST_VALID_JS_ACTION &&
56 action <= SYNC_PROMO_LAST_VALID_JS_ACTION) ||
57 action == SYNC_PROMO_LEFT_DURING_THROBBER;
58 }
59
60 } // namespace
61
62 SyncPromoHandler2::SyncPromoHandler2(ProfileManager* profile_manager)
63 : SyncSetupHandler2(profile_manager),
64 window_already_closed_(false) {
65 }
66
67 SyncPromoHandler2::~SyncPromoHandler2() {
68 }
69
70 // static
71 void SyncPromoHandler2::RegisterUserPrefs(PrefService* prefs) {
72 prefs->RegisterIntegerPref(prefs::kSyncPromoViewCount, 0,
73 PrefService::UNSYNCABLE_PREF);
74 prefs->RegisterBooleanPref(prefs::kSyncPromoShowNTPBubble, false,
75 PrefService::UNSYNCABLE_PREF);
76 }
77
78 WebUIMessageHandler* SyncPromoHandler2::Attach(WebUI* web_ui) {
79 DCHECK(web_ui);
80 // Keep a reference to the preferences service for convenience and it's
81 // probably a little faster that getting it via Profile::FromWebUI() every
82 // time we need to interact with preferences.
83 prefs_ = Profile::FromWebUI(web_ui)->GetPrefs();
84 DCHECK(prefs_);
85 // Ignore events from view-source:chrome://syncpromo.
86 if (!web_ui->tab_contents()->controller().GetActiveEntry()->
87 IsViewSourceMode()) {
88 // Listen to see if the tab we're in gets closed.
89 registrar_.Add(this, content::NOTIFICATION_TAB_CLOSING,
90 content::Source<NavigationController>(
91 &web_ui->tab_contents()->controller()));
92 // Listen to see if the window we're in gets closed.
93 registrar_.Add(this, chrome::NOTIFICATION_BROWSER_CLOSING,
94 content::NotificationService::AllSources());
95 }
96 return SyncSetupHandler2::Attach(web_ui);
97 }
98
99 void SyncPromoHandler2::RegisterMessages() {
100 web_ui_->RegisterMessageCallback("SyncPromo:Close",
101 base::Bind(&SyncPromoHandler2::HandleCloseSyncPromo,
102 base::Unretained(this)));
103 web_ui_->RegisterMessageCallback("SyncPromo:Initialize",
104 base::Bind(&SyncPromoHandler2::HandleInitializeSyncPromo,
105 base::Unretained(this)));
106 web_ui_->RegisterMessageCallback("SyncPromo:RecordSignInAttempts",
107 base::Bind(&SyncPromoHandler2::HandleRecordSignInAttempts,
108 base::Unretained(this)));
109 web_ui_->RegisterMessageCallback("SyncPromo:RecordThrobberTime",
110 base::Bind(&SyncPromoHandler2::HandleRecordThrobberTime,
111 base::Unretained(this)));
112 web_ui_->RegisterMessageCallback("SyncPromo:ShowAdvancedSettings",
113 base::Bind(&SyncPromoHandler2::HandleShowAdvancedSettings,
114 base::Unretained(this)));
115 web_ui_->RegisterMessageCallback("SyncPromo:UserFlowAction",
116 base::Bind(&SyncPromoHandler2::HandleUserFlowAction,
117 base::Unretained(this)));
118 web_ui_->RegisterMessageCallback("SyncPromo:UserSkipped",
119 base::Bind(&SyncPromoHandler2::HandleUserSkipped,
120 base::Unretained(this)));
121 SyncSetupHandler2::RegisterMessages();
122 }
123
124 void SyncPromoHandler2::ShowGaiaSuccessAndClose() {
125 if (sync_promo_trial::IsExperimentActive())
126 sync_promo_trial::RecordUserSignedIn();
127
128 SyncSetupHandler2::ShowGaiaSuccessAndClose();
129 }
130
131 void SyncPromoHandler2::ShowGaiaSuccessAndSettingUp() {
132 if (sync_promo_trial::IsExperimentActive())
133 sync_promo_trial::RecordUserSignedIn();
134
135 SyncSetupHandler2::ShowGaiaSuccessAndSettingUp();
136 }
137
138 void SyncPromoHandler2::ShowConfigure(const base::DictionaryValue& args) {
139 bool usePassphrase = false;
140 args.GetBoolean("usePassphrase", &usePassphrase);
141
142 if (usePassphrase) {
143 // If a passphrase is required then we must show the configure pane.
144 SyncSetupHandler2::ShowConfigure(args);
145 } else {
146 // If no passphrase is required then skip the configure pane and sync
147 // everything by default. This makes the first run experience simpler.
148 // Note, there's an advanced link in the sync promo that takes users
149 // to Settings where the configure pane is not skipped.
150 SyncConfiguration configuration;
151 configuration.sync_everything = true;
152 DCHECK(flow());
153 flow()->OnUserConfigured(configuration);
154 }
155 }
156
157 void SyncPromoHandler2::Observe(int type,
158 const content::NotificationSource& source,
159 const content::NotificationDetails& details) {
160 switch (type) {
161 case content::NOTIFICATION_TAB_CLOSING: {
162 if (!window_already_closed_)
163 RecordUserFlowAction(SYNC_PROMO_CLOSED_TAB);
164 break;
165 }
166 case chrome::NOTIFICATION_BROWSER_CLOSING: {
167 // Make sure we're in the tab strip of the closing window.
168 Browser* browser = content::Source<Browser>(source).ptr();
169 if (browser->tabstrip_model()->GetWrapperIndex(
170 web_ui_->tab_contents()) != TabStripModel::kNoTab) {
171 RecordUserFlowAction(SYNC_PROMO_CLOSED_WINDOW);
172 window_already_closed_ = true;
173 }
174 break;
175 }
176 default: {
177 NOTREACHED();
178 }
179 }
180 }
181
182 void SyncPromoHandler2::StepWizardForShowSetupUI() {
183 ProfileSyncService* service =
184 Profile::FromWebUI(web_ui_)->GetProfileSyncService();
185 service->get_wizard().Step(SyncSetupWizard::GetLoginState());
186 }
187
188 void SyncPromoHandler2::ShowSetupUI() {
189 // We don't need to do anything here; The UI for the sync promo is already
190 // displayed.
191 }
192
193 void SyncPromoHandler2::HandleCloseSyncPromo(const base::ListValue* args) {
194 CloseSyncSetup();
195
196 // If the user has signed in then set the pref to show them NTP bubble
197 // confirming that they're signed in.
198 std::string username = prefs_->GetString(prefs::kGoogleServicesUsername);
199 if (!username.empty())
200 prefs_->SetBoolean(prefs::kSyncPromoShowNTPBubble, true);
201
202 GURL url = SyncPromoUI::GetNextPageURLForSyncPromoURL(
203 web_ui_->tab_contents()->GetURL());
204 web_ui_->tab_contents()->OpenURL(url, GURL(), CURRENT_TAB,
205 content::PAGE_TRANSITION_LINK);
206 }
207
208 void SyncPromoHandler2::HandleInitializeSyncPromo(const base::ListValue* args) {
209 // If the promo is also the Chrome launch page, we want to show the title and
210 // log an event if we are running an experiment.
211 bool is_launch_page = SyncPromoUI::GetIsLaunchPageForSyncPromoURL(
212 web_ui_->tab_contents()->GetURL());
213 if (is_launch_page && sync_promo_trial::IsExperimentActive())
214 sync_promo_trial::RecordUserSawMessage();
215 base::FundamentalValue visible(is_launch_page);
216 web_ui_->CallJavascriptFunction("SyncSetupOverlay.setPromoTitleVisible",
217 visible);
218
219 OpenSyncSetup();
220 // We don't need to compute anything for this, just do this every time.
221 RecordUserFlowAction(SYNC_PROMO_VIEWED);
222 // Increment view count first and show natural numbers in stats rather than 0
223 // based starting point (if it happened to be our first time showing this).
224 IncrementViewCountBy(1);
225 // Record +1 for every view. This is the only thing we record that's not part
226 // of the user flow histogram.
227 UMA_HISTOGRAM_COUNTS("SyncPromo.NumTimesViewed", GetViewCount());
228 }
229
230 void SyncPromoHandler2::HandleShowAdvancedSettings(
231 const base::ListValue* args) {
232 CloseSyncSetup();
233 std::string url(chrome::kChromeUISettingsURL);
234 url += chrome::kSyncSetupSubPage;
235 web_ui_->tab_contents()->OpenURL(GURL(url), GURL(), CURRENT_TAB,
236 content::PAGE_TRANSITION_LINK);
237 RecordUserFlowAction(SYNC_PROMO_ADVANCED_CLICKED);
238 }
239
240 // TODO(dbeam): Replace with metricsHandler:recordHistogramTime when it exists.
241 void SyncPromoHandler2::HandleRecordThrobberTime(const base::ListValue* args) {
242 double time_double;
243 CHECK(args->GetDouble(0, &time_double));
244 UMA_HISTOGRAM_TIMES("SyncPromo.ThrobberTime",
245 base::TimeDelta::FromMilliseconds(time_double));
246 }
247
248 // TODO(dbeam): Replace with metricsHandler:recordHistogramCount when it exists.
249 void SyncPromoHandler2::HandleRecordSignInAttempts(const base::ListValue* args) {
250 double count_double;
251 CHECK(args->GetDouble(0, &count_double));
252 UMA_HISTOGRAM_COUNTS("SyncPromo.SignInAttempts", count_double);
253 }
254
255 void SyncPromoHandler2::HandleUserFlowAction(const base::ListValue* args) {
256 double action_double;
257 CHECK(args->GetDouble(0, &action_double));
258 int action = static_cast<int>(action_double);
259
260 if (IsValidUserFlowAction(action))
261 RecordUserFlowAction(action);
262 else
263 NOTREACHED() << "Attempt to record invalid user flow action on sync promo.";
264 }
265
266 void SyncPromoHandler2::HandleUserSkipped(const base::ListValue* args) {
267 SyncPromoUI::SetUserSkippedSyncPromo(Profile::FromWebUI(web_ui_));
268 RecordUserFlowAction(SYNC_PROMO_SKIP_CLICKED);
269 }
270
271 int SyncPromoHandler2::GetViewCount() const {
272 // The locally persistent number of times the user has seen the sync promo.
273 return prefs_->GetInteger(prefs::kSyncPromoViewCount);
274 }
275
276 int SyncPromoHandler2::IncrementViewCountBy(unsigned int amount) {
277 // Let the user increment by 0 if they really want. It might be useful for a
278 // weird way of sending preference change notifications...
279 int adjusted = GetViewCount() + amount;
280 prefs_->SetInteger(prefs::kSyncPromoViewCount, adjusted);
281 return adjusted;
282 }
283
284 void SyncPromoHandler2::RecordUserFlowAction(int action) {
285 // Send an enumeration to our single user flow histogram.
286 UMA_HISTOGRAM_ENUMERATION("SyncPromo.UserFlow", action,
287 SYNC_PROMO_BUCKET_BOUNDARY);
288 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/webui/sync_promo_handler2.h ('k') | chrome/browser/ui/webui/sync_setup_handler2.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698