summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordbeam@chromium.org <dbeam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-11-17 00:51:10 +0000
committerdbeam@chromium.org <dbeam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-11-17 00:51:10 +0000
commite91b6b59f46a1ca808a65ecd35c568162326abe2 (patch)
treeb605bf806dcbcbccc2c0984d410ff1fb954cd654
parent37f7156f6b0ccdc39a9fdc1a836128ff0d500bd5 (diff)
downloadchromium_src-e91b6b59f46a1ca808a65ecd35c568162326abe2.zip
chromium_src-e91b6b59f46a1ca808a65ecd35c568162326abe2.tar.gz
chromium_src-e91b6b59f46a1ca808a65ecd35c568162326abe2.tar.bz2
Merge 110354 - Sync Promo: Add more UMA metrics.
R=estade@chromium.org BUG=103822 TEST=+1 action in SyncPromo.UserFlowAction and +2 new histograms. Review URL: http://codereview.chromium.org/8528054 TBR=dbeam@chromium.org Review URL: http://codereview.chromium.org/8586010 git-svn-id: svn://svn.chromium.org/chrome/branches/912/src@110404 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/resources/sync_promo.js56
-rw-r--r--chrome/browser/resources/sync_setup_overlay.js11
-rw-r--r--chrome/browser/ui/webui/metrics_handler.h2
-rw-r--r--chrome/browser/ui/webui/sync_promo_handler.cc90
-rw-r--r--chrome/browser/ui/webui/sync_promo_handler.h21
-rw-r--r--chrome/common/extensions/extension_constants.h22
6 files changed, 154 insertions, 48 deletions
diff --git a/chrome/browser/resources/sync_promo.js b/chrome/browser/resources/sync_promo.js
index d387518..03341f3 100644
--- a/chrome/browser/resources/sync_promo.js
+++ b/chrome/browser/resources/sync_promo.js
@@ -32,6 +32,7 @@ cr.define('sync_promo', function() {
CONFIRMED_AFTER_SIGN_IN: i++,
CLOSED_TAB: i++,
CLOSED_WINDOW: i++,
+ LEFT_DURING_THROBBER: i++,
};
}());
@@ -64,7 +65,7 @@ cr.define('sync_promo', function() {
var self = this;
$('promo-skip-button').addEventListener('click', function() {
- chrome.send('SyncPromo:UserFlowAction', [actions.SKIP_CLICKED]);
+ chrome.send('SyncPromo:UserSkipped');
self.closeOverlay_();
});
@@ -104,6 +105,7 @@ cr.define('sync_promo', function() {
// we also track users that use the keyboard and press enter.
var signInAttemptedAlready = false;
$('gaia-login-form').addEventListener('submit', function() {
+ ++self.signInAttempts_;
if (!signInAttemptedAlready)
chrome.send('SyncPromo:UserFlowAction', [actions.SIGN_IN_ATTEMPTED]);
signInAttemptedAlready = true;
@@ -142,6 +144,17 @@ cr.define('sync_promo', function() {
},
/**
+ * Called when the page is unloading to record number of times a user tried
+ * to sign in and if they left while a throbber was running.
+ * @private
+ */
+ recordPageViewActions_: function() {
+ chrome.send('SyncPromo:RecordSignInAttempts', [this.signInAttempts_]);
+ if (this.throbberStart_)
+ chrome.send('SyncPromo:UserFlowAction', [actions.LEFT_DURING_THROBBER]);
+ },
+
+ /**
* Remove the [hidden] attribute from the node that was not previously
* transitioning.
* @param {Event} e A -webkit-transition end event.
@@ -188,7 +201,36 @@ cr.define('sync_promo', function() {
*/
setPromoTitleVisible_: function(visible) {
$('promo-title').hidden = !visible;
- }
+ },
+
+ /** @inheritDoc */
+ setThrobbersVisible_: function(visible) {
+ if (visible) {
+ this.throbberStart_ = Date.now();
+ } else {
+ if (this.throbberStart_) {
+ chrome.send('SyncPromo:RecordThrobberTime',
+ [Date.now() - this.throbberStart_]);
+ }
+ this.throbberStart_ = 0;
+ }
+ // Pass through to SyncSetupOverlay to handle display logic.
+ options.SyncSetupOverlay.prototype.setThrobbersVisible_.apply(
+ this, arguments);
+ },
+
+ /**
+ * Number of times a user attempted to sign in to GAIA during this page
+ * view.
+ * @private
+ */
+ signInAttempts_: 0,
+
+ /**
+ * The start time of a throbber on the page.
+ * @private
+ */
+ throbberStart_: 0,
};
SyncPromo.showErrorUI = function() {
@@ -222,14 +264,20 @@ cr.define('sync_promo', function() {
SyncPromo.setPromoTitleVisible = function(visible) {
SyncPromo.getInstance().setPromoTitleVisible_(visible);
- }
+ };
+
+ SyncPromo.recordPageViewActions = function() {
+ SyncPromo.getInstance().recordPageViewActions_();
+ };
// Export
return {
- SyncPromo : SyncPromo
+ SyncPromo: SyncPromo
};
});
var OptionsPage = options.OptionsPage;
var SyncSetupOverlay = sync_promo.SyncPromo;
window.addEventListener('DOMContentLoaded', sync_promo.SyncPromo.initialize);
+window.addEventListener('beforeunload',
+ sync_promo.SyncPromo.recordPageViewActions.bind(sync_promo.SyncPromo));
diff --git a/chrome/browser/resources/sync_setup_overlay.js b/chrome/browser/resources/sync_setup_overlay.js
index 8e3a955..920c84f 100644
--- a/chrome/browser/resources/sync_setup_overlay.js
+++ b/chrome/browser/resources/sync_setup_overlay.js
@@ -545,10 +545,15 @@ cr.define('options', function() {
this.showOverlay_();
},
+ /**
+ * Changes the visibility of throbbers on this page.
+ * @param {boolean} visible Whether or not to set all throbber nodes
+ * visible.
+ */
setThrobbersVisible_: function(visible) {
var throbbers = document.getElementsByClassName("throbber");
- for (var i = 0; i < throbbers.length; i++)
- throbbers[i].style.visibility = visible ? "visible" : "hidden";
+ for (var i = 0; i < throbbers.length; i++)
+ throbbers[i].style.visibility = visible ? "visible" : "hidden";
},
loginSetFocus_: function() {
@@ -751,7 +756,7 @@ cr.define('options', function() {
$('captcha-value').disabled = true;
$('access-code').disabled = true;
- $('logging-in-throbber').style.visibility = "visible";
+ this.setThrobbersVisible_(true);
var f = $('gaia-login-form');
var email = $('gaia-email');
diff --git a/chrome/browser/ui/webui/metrics_handler.h b/chrome/browser/ui/webui/metrics_handler.h
index b86dbf2..2f6c693 100644
--- a/chrome/browser/ui/webui/metrics_handler.h
+++ b/chrome/browser/ui/webui/metrics_handler.h
@@ -33,6 +33,8 @@ class MetricsHandler : public WebUIMessageHandler {
// user action.
void HandleRecordAction(const base::ListValue* args);
+ // TODO(dbeam): http://crbug.com/104338
+
// Callback for the "metricsHandler:recordInHistogram" message. This records
// into a histogram. |args| contains the histogram name, the value to record,
// and the maximum allowed value, which can be at most 4000. The histogram
diff --git a/chrome/browser/ui/webui/sync_promo_handler.cc b/chrome/browser/ui/webui/sync_promo_handler.cc
index ed69584..7540790 100644
--- a/chrome/browser/ui/webui/sync_promo_handler.cc
+++ b/chrome/browser/ui/webui/sync_promo_handler.cc
@@ -7,6 +7,7 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/metrics/histogram.h"
+#include "base/time.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/sync/profile_sync_service.h"
@@ -20,8 +21,42 @@
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
#include "content/browser/tab_contents/tab_contents.h"
-#include "content/common/notification_details.h"
-#include "content/common/notification_service.h"
+#include "content/public/browser/notification_details.h"
+#include "content/public/browser/notification_service.h"
+
+namespace {
+
+// User actions on the sync promo (aka "Sign in to Chrome").
+enum SyncPromoUserFlowActionEnums {
+ SYNC_PROMO_VIEWED,
+ SYNC_PROMO_LEARN_MORE_CLICKED,
+ SYNC_PROMO_ACCOUNT_HELP_CLICKED,
+ SYNC_PROMO_CREATE_ACCOUNT_CLICKED,
+ SYNC_PROMO_SKIP_CLICKED,
+ SYNC_PROMO_SIGN_IN_ATTEMPTED,
+ SYNC_PROMO_SIGNED_IN_SUCCESSFULLY,
+ SYNC_PROMO_ADVANCED_CLICKED,
+ SYNC_PROMO_ENCRYPTION_HELP_CLICKED,
+ SYNC_PROMO_CANCELLED_AFTER_SIGN_IN,
+ SYNC_PROMO_CONFIRMED_AFTER_SIGN_IN,
+ SYNC_PROMO_CLOSED_TAB,
+ SYNC_PROMO_CLOSED_WINDOW,
+ SYNC_PROMO_LEFT_DURING_THROBBER,
+ SYNC_PROMO_BUCKET_BOUNDARY,
+ SYNC_PROMO_FIRST_VALID_JS_ACTION = SYNC_PROMO_LEARN_MORE_CLICKED,
+ SYNC_PROMO_LAST_VALID_JS_ACTION = SYNC_PROMO_CONFIRMED_AFTER_SIGN_IN,
+};
+
+// This was added because of the need to change the existing UMA enum for the
+// sync promo mid-flight. Ideally these values would be contiguous, but the
+// real world is not always ideal.
+static bool IsValidUserFlowAction(int action) {
+ return (action >= SYNC_PROMO_FIRST_VALID_JS_ACTION &&
+ action <= SYNC_PROMO_LAST_VALID_JS_ACTION) ||
+ action == SYNC_PROMO_LEFT_DURING_THROBBER;
+}
+
+} // namespace
SyncPromoHandler::SyncPromoHandler(ProfileManager* profile_manager)
: SyncSetupHandler(profile_manager),
@@ -66,12 +101,21 @@ void SyncPromoHandler::RegisterMessages() {
web_ui_->RegisterMessageCallback("SyncPromo:Initialize",
base::Bind(&SyncPromoHandler::HandleInitializeSyncPromo,
base::Unretained(this)));
- web_ui_->RegisterMessageCallback("SyncPromo:UserFlowAction",
- base::Bind(&SyncPromoHandler::HandleUserFlowAction,
+ web_ui_->RegisterMessageCallback("SyncPromo:RecordSignInAttempts",
+ base::Bind(&SyncPromoHandler::HandleRecordSignInAttempts,
+ base::Unretained(this)));
+ web_ui_->RegisterMessageCallback("SyncPromo:RecordThrobberTime",
+ base::Bind(&SyncPromoHandler::HandleRecordThrobberTime,
base::Unretained(this)));
web_ui_->RegisterMessageCallback("SyncPromo:ShowAdvancedSettings",
base::Bind(&SyncPromoHandler::HandleShowAdvancedSettings,
base::Unretained(this)));
+ web_ui_->RegisterMessageCallback("SyncPromo:UserFlowAction",
+ base::Bind(&SyncPromoHandler::HandleUserFlowAction,
+ base::Unretained(this)));
+ web_ui_->RegisterMessageCallback("SyncPromo:UserSkipped",
+ base::Bind(&SyncPromoHandler::HandleUserSkipped,
+ base::Unretained(this)));
SyncSetupHandler::RegisterMessages();
}
@@ -100,7 +144,7 @@ void SyncPromoHandler::Observe(int type,
switch (type) {
case content::NOTIFICATION_TAB_CLOSING: {
if (!window_already_closed_)
- RecordUserFlowAction(extension_misc::SYNC_PROMO_CLOSED_TAB);
+ RecordUserFlowAction(SYNC_PROMO_CLOSED_TAB);
break;
}
case chrome::NOTIFICATION_BROWSER_CLOSING: {
@@ -108,7 +152,7 @@ void SyncPromoHandler::Observe(int type,
Browser* browser = Source<Browser>(source).ptr();
if (browser->tabstrip_model()->GetWrapperIndex(
web_ui_->tab_contents()) != TabStripModel::kNoTab) {
- RecordUserFlowAction(extension_misc::SYNC_PROMO_CLOSED_WINDOW);
+ RecordUserFlowAction(SYNC_PROMO_CLOSED_WINDOW);
window_already_closed_ = true;
}
break;
@@ -148,7 +192,7 @@ void SyncPromoHandler::HandleInitializeSyncPromo(const base::ListValue* args) {
OpenSyncSetup();
// We don't need to compute anything for this, just do this every time.
- RecordUserFlowAction(extension_misc::SYNC_PROMO_VIEWED);
+ RecordUserFlowAction(SYNC_PROMO_VIEWED);
// Increment view count first and show natural numbers in stats rather than 0
// based starting point (if it happened to be our first time showing this).
IncrementViewCountBy(1);
@@ -164,22 +208,38 @@ void SyncPromoHandler::HandleShowAdvancedSettings(
url += chrome::kSyncSetupSubPage;
web_ui_->tab_contents()->OpenURL(GURL(url), GURL(), CURRENT_TAB,
content::PAGE_TRANSITION_LINK);
- RecordUserFlowAction(extension_misc::SYNC_PROMO_ADVANCED_CLICKED);
+ RecordUserFlowAction(SYNC_PROMO_ADVANCED_CLICKED);
+}
+
+// TODO(dbeam): Replace with metricsHandler:recordHistogramTime when it exists.
+void SyncPromoHandler::HandleRecordThrobberTime(const base::ListValue* args) {
+ double time_double;
+ CHECK(args->GetDouble(0, &time_double));
+ UMA_HISTOGRAM_TIMES("SyncPromo.ThrobberTime",
+ base::TimeDelta::FromMilliseconds(time_double));
+}
+
+// TODO(dbeam): Replace with metricsHandler:recordHistogramCount when it exists.
+void SyncPromoHandler::HandleRecordSignInAttempts(const base::ListValue* args) {
+ double count_double;
+ CHECK(args->GetDouble(0, &count_double));
+ UMA_HISTOGRAM_COUNTS("SyncPromo.SignInAttempts", count_double);
}
void SyncPromoHandler::HandleUserFlowAction(const base::ListValue* args) {
double action_double;
CHECK(args->GetDouble(0, &action_double));
int action = static_cast<int>(action_double);
- if (action >= extension_misc::SYNC_PROMO_FIRST_VALID_JS_ACTION &&
- action <= extension_misc::SYNC_PROMO_LAST_VALID_JS_ACTION) {
+
+ if (IsValidUserFlowAction(action))
RecordUserFlowAction(action);
- } else {
+ else
NOTREACHED() << "Attempt to record invalid user flow action on sync promo.";
- }
+}
- if (action == extension_misc::SYNC_PROMO_SKIP_CLICKED)
- SyncPromoUI::SetUserSkippedSyncPromo(Profile::FromWebUI(web_ui_));
+void SyncPromoHandler::HandleUserSkipped(const base::ListValue* args) {
+ SyncPromoUI::SetUserSkippedSyncPromo(Profile::FromWebUI(web_ui_));
+ RecordUserFlowAction(SYNC_PROMO_SKIP_CLICKED);
}
int SyncPromoHandler::GetViewCount() const {
@@ -198,5 +258,5 @@ int SyncPromoHandler::IncrementViewCountBy(unsigned int amount) {
void SyncPromoHandler::RecordUserFlowAction(int action) {
// Send an enumeration to our single user flow histogram.
UMA_HISTOGRAM_ENUMERATION("SyncPromo.UserFlow", action,
- extension_misc::SYNC_PROMO_BUCKET_BOUNDARY);
+ SYNC_PROMO_BUCKET_BOUNDARY);
}
diff --git a/chrome/browser/ui/webui/sync_promo_handler.h b/chrome/browser/ui/webui/sync_promo_handler.h
index bd1c1b1..b128bed 100644
--- a/chrome/browser/ui/webui/sync_promo_handler.h
+++ b/chrome/browser/ui/webui/sync_promo_handler.h
@@ -11,7 +11,7 @@
class NotificationSource;
class NotificationDetails;
-// The handler for Javascript messages related to the "sync promo" page.
+// The handler for JavaScript messages related to the "sync promo" page.
class SyncPromoHandler : public SyncSetupHandler {
public:
explicit SyncPromoHandler(ProfileManager* profile_manager);
@@ -37,19 +37,30 @@ class SyncPromoHandler : public SyncSetupHandler {
virtual void ShowSetupUI() OVERRIDE;
private:
- // Javascript callback handler to close the sync promo.
+ // JavaScript callback handler to close the sync promo.
void HandleCloseSyncPromo(const base::ListValue* args);
- // Javascript callback handler to initialize the sync promo.
+ // JavaScript callback handler to initialize the sync promo.
void HandleInitializeSyncPromo(const base::ListValue* args);
- // Javascript callback handler to switch the advanced sync settings. |args| is
+ // JavaScript handler to record the duration for which the throbber was
+ // visible during an attempted sign-in flow.
+ void HandleRecordThrobberTime(const base::ListValue* args);
+
+ // JavaScript handler to record the number of times a user attempted to sign
+ // in to chrome while they were on the sync promo page.
+ void HandleRecordSignInAttempts(const base::ListValue* args);
+
+ // JavaScript callback handler to switch the advanced sync settings. |args| is
// the list of arguments passed from JS and should be an empty list.
void HandleShowAdvancedSettings(const base::ListValue* args);
- // Javascript callback handler to record user actions on the sync promo.
+ // JavaScript callback handler to record user actions on the sync promo.
void HandleUserFlowAction(const base::ListValue* args);
+ // JavaScript callback handler for when a user clicks skip.
+ void HandleUserSkipped(const base::ListValue* args);
+
// Return the number of times the user with the current profile has seen the
// sync promo.
int GetViewCount() const;
diff --git a/chrome/common/extensions/extension_constants.h b/chrome/common/extensions/extension_constants.h
index 804fb0e..7dd3315 100644
--- a/chrome/common/extensions/extension_constants.h
+++ b/chrome/common/extensions/extension_constants.h
@@ -455,26 +455,6 @@ namespace extension_misc {
UNLOAD_REASON_UPDATE, // Extension is being updated to a newer version.
UNLOAD_REASON_UNINSTALL, // Extension is being uninstalled.
};
-
- // User actions on the sync promo (aka "Sign in to Chrome").
- enum SyncPromoBuckets {
- SYNC_PROMO_VIEWED,
- SYNC_PROMO_LEARN_MORE_CLICKED,
- SYNC_PROMO_ACCOUNT_HELP_CLICKED,
- SYNC_PROMO_CREATE_ACCOUNT_CLICKED,
- SYNC_PROMO_SKIP_CLICKED,
- SYNC_PROMO_SIGN_IN_ATTEMPTED,
- SYNC_PROMO_SIGNED_IN_SUCCESSFULLY,
- SYNC_PROMO_ADVANCED_CLICKED,
- SYNC_PROMO_ENCRYPTION_HELP_CLICKED,
- SYNC_PROMO_CANCELLED_AFTER_SIGN_IN,
- SYNC_PROMO_CONFIRMED_AFTER_SIGN_IN,
- SYNC_PROMO_CLOSED_TAB,
- SYNC_PROMO_CLOSED_WINDOW,
- SYNC_PROMO_BUCKET_BOUNDARY,
- SYNC_PROMO_FIRST_VALID_JS_ACTION = SYNC_PROMO_LEARN_MORE_CLICKED,
- SYNC_PROMO_LAST_VALID_JS_ACTION = SYNC_PROMO_CONFIRMED_AFTER_SIGN_IN,
- };
-} // extension_misc
+} // extension_misc
#endif // CHROME_COMMON_EXTENSIONS_EXTENSION_CONSTANTS_H_