diff options
author | ahutter@chromium.org <ahutter@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-02 03:06:47 +0000 |
---|---|---|
committer | ahutter@chromium.org <ahutter@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-02 03:06:47 +0000 |
commit | 4fe048910c04087cd746640bb8e2d96ff763f187 (patch) | |
tree | d6c2438e6bf4eeb5931298aae0706afd597119da /components | |
parent | e2f64e3ec6c7b31801b1ae8a6d8bd7354bb7b3b1 (diff) | |
download | chromium_src-4fe048910c04087cd746640bb8e2d96ff763f187.zip chromium_src-4fe048910c04087cd746640bb8e2d96ff763f187.tar.gz chromium_src-4fe048910c04087cd746640bb8e2d96ff763f187.tar.bz2 |
Logging more UMA metrics for Autocheckout.
BUG=222254
Review URL: https://chromiumcodereview.appspot.com/13270004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@191748 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'components')
5 files changed, 200 insertions, 13 deletions
diff --git a/components/autofill/browser/autocheckout_manager.cc b/components/autofill/browser/autocheckout_manager.cc index fbb9115..f02f0bc 100644 --- a/components/autofill/browser/autocheckout_manager.cc +++ b/components/autofill/browser/autocheckout_manager.cc @@ -11,6 +11,7 @@ #include "components/autofill/browser/autofill_country.h" #include "components/autofill/browser/autofill_field.h" #include "components/autofill/browser/autofill_manager.h" +#include "components/autofill/browser/autofill_metrics.h" #include "components/autofill/browser/autofill_profile.h" #include "components/autofill/browser/credit_card.h" #include "components/autofill/browser/field_types.h" @@ -29,6 +30,8 @@ using content::RenderViewHost; using content::SSLStatus; using content::WebContents; +namespace autofill { + namespace { // Build FormFieldData based on the supplied |autocomplete_attribute|. Will @@ -68,14 +71,30 @@ FormData BuildAutocheckoutFormData() { return formdata; } +AutofillMetrics::AutocheckoutBuyFlowMetric AutocheckoutStatusToUmaMetric( + AutocheckoutStatus status) { + switch (status) { + case SUCCESS: + return AutofillMetrics::AUTOCHECKOUT_BUY_FLOW_SUCCESS; + case MISSING_FIELDMAPPING: + return AutofillMetrics::AUTOCHECKOUT_BUY_FLOW_MISSING_FIELDMAPPING; + case MISSING_ADVANCE: + return AutofillMetrics::AUTOCHECKOUT_BUY_FLOW_MISSING_ADVANCE_ELEMENT; + case CANNOT_PROCEED: + return AutofillMetrics::AUTOCHECKOUT_BUY_FLOW_CANNOT_PROCEED; + } + + NOTREACHED(); + return AutofillMetrics::NUM_AUTOCHECKOUT_BUY_FLOW_METRICS; +} + const char kTransactionIdNotSet[] = "transaction id not set"; } // namespace -namespace autofill { - AutocheckoutManager::AutocheckoutManager(AutofillManager* autofill_manager) : autofill_manager_(autofill_manager), + metric_logger_(new AutofillMetrics), autocheckout_offered_(false), is_autocheckout_bubble_showing_(false), in_autocheckout_flow_(false), @@ -120,8 +139,12 @@ void AutocheckoutManager::FillForms() { } void AutocheckoutManager::OnClickFailed(AutocheckoutStatus status) { + DCHECK(in_autocheckout_flow_); + DCHECK_NE(MISSING_FIELDMAPPING, status); + SendAutocheckoutStatus(status); autofill_manager_->delegate()->OnAutocheckoutError(); + in_autocheckout_flow_ = false; } void AutocheckoutManager::OnLoadedPageMetaData( @@ -130,6 +153,14 @@ void AutocheckoutManager::OnLoadedPageMetaData( page_meta_data_.Pass(); page_meta_data_ = page_meta_data.Pass(); + // Don't log that the bubble could be displayed if the user entered an + // Autocheckout flow and sees the first page of the flow again due to an + // error. + if (IsStartOfAutofillableFlow() && !in_autocheckout_flow_) { + metric_logger_->LogAutocheckoutBubbleMetric( + AutofillMetrics::BUBBLE_COULD_BE_DISPLAYED); + } + // On the first page of an Autocheckout flow, when this function is called the // user won't have opted into the flow yet. if (!in_autocheckout_flow_) @@ -203,6 +234,11 @@ void AutocheckoutManager::MaybeShowAutocheckoutBubble( autocheckout_offered_ = true; } +void AutocheckoutManager::set_metric_logger( + scoped_ptr<AutofillMetrics> metric_logger) { + metric_logger_ = metric_logger.Pass(); +} + void AutocheckoutManager::MaybeShowAutocheckoutDialog( const GURL& frame_url, const SSLStatus& ssl_status, @@ -236,6 +272,8 @@ void AutocheckoutManager::ReturnAutocheckoutData( google_transaction_id_ = google_transaction_id; in_autocheckout_flow_ = true; + metric_logger_->LogAutocheckoutBuyFlowMetric( + AutofillMetrics::AUTOCHECKOUT_BUY_FLOW_STARTED); profile_.reset(new AutofillProfile()); credit_card_.reset(new CreditCard()); @@ -324,6 +362,10 @@ void AutocheckoutManager::SendAutocheckoutStatus(AutocheckoutStatus status) { autofill_manager_->GetWebContents()->GetURL(), google_transaction_id_); + // Log the result of this Autocheckout flow to UMA. + metric_logger_->LogAutocheckoutBuyFlowMetric( + AutocheckoutStatusToUmaMetric(status)); + google_transaction_id_ = kTransactionIdNotSet; } diff --git a/components/autofill/browser/autocheckout_manager.h b/components/autofill/browser/autocheckout_manager.h index ffe2b2e..76ca993 100644 --- a/components/autofill/browser/autocheckout_manager.h +++ b/components/autofill/browser/autocheckout_manager.h @@ -16,6 +16,7 @@ class AutofillField; class AutofillManager; +class AutofillMetrics; class AutofillProfile; class CreditCard; class FormStructure; @@ -81,6 +82,9 @@ class AutocheckoutManager { const content::SSLStatus& ssl_status, bool show_dialog); + const AutofillMetrics& metric_logger() const { return *metric_logger_; } + void set_metric_logger(scoped_ptr<AutofillMetrics> metric_logger); + private: // Whether or not the current page is the start of a multipage Autofill flow. bool IsStartOfAutofillableFlow() const; @@ -113,6 +117,8 @@ class AutocheckoutManager { // Autocheckout specific page meta data. scoped_ptr<AutocheckoutPageMetaData> page_meta_data_; + scoped_ptr<AutofillMetrics> metric_logger_; + // Whether or not the Autocheckout bubble has been displayed to the user for // the current forms. Ensures the Autocheckout bubble is only shown to a // user once per pageview. diff --git a/components/autofill/browser/autocheckout_manager_unittest.cc b/components/autofill/browser/autocheckout_manager_unittest.cc index 280e249..33440f2 100644 --- a/components/autofill/browser/autocheckout_manager_unittest.cc +++ b/components/autofill/browser/autocheckout_manager_unittest.cc @@ -9,6 +9,7 @@ #include "components/autofill/browser/autocheckout_manager.h" #include "components/autofill/browser/autofill_common_test.h" #include "components/autofill/browser/autofill_manager.h" +#include "components/autofill/browser/autofill_metrics.h" #include "components/autofill/browser/form_structure.h" #include "components/autofill/browser/test_autofill_manager_delegate.h" #include "components/autofill/common/autofill_messages.h" @@ -144,6 +145,13 @@ scoped_ptr<AutocheckoutPageMetaData> CreateInFlowMetaData() { return in_flow.Pass(); } +scoped_ptr<AutocheckoutPageMetaData> CreateNotInFlowMetaData() { + scoped_ptr<AutocheckoutPageMetaData> not_in_flow( + new AutocheckoutPageMetaData()); + not_in_flow->proceed_element_descriptor = CreateProceedElement().Pass(); + return not_in_flow.Pass(); +} + scoped_ptr<AutocheckoutPageMetaData> CreateEndOfFlowMetaData() { scoped_ptr<AutocheckoutPageMetaData> end_of_flow( new AutocheckoutPageMetaData()); @@ -282,15 +290,32 @@ class TestAutofillManager : public AutofillManager { } }; +class MockAutofillMetrics : public AutofillMetrics { + public: + MockAutofillMetrics() {} + MOCK_CONST_METHOD1(LogAutocheckoutBubbleMetric, void(BubbleMetric)); + MOCK_CONST_METHOD1(LogAutocheckoutBuyFlowMetric, + void(AutocheckoutBuyFlowMetric)); + + private: + DISALLOW_COPY_AND_ASSIGN(MockAutofillMetrics); +}; class TestAutocheckoutManager: public AutocheckoutManager { - public: - explicit TestAutocheckoutManager(AutofillManager* autofill_manager) - : AutocheckoutManager(autofill_manager) {} + public: + explicit TestAutocheckoutManager(AutofillManager* autofill_manager) + : AutocheckoutManager(autofill_manager) { + set_metric_logger(scoped_ptr<AutofillMetrics>(new MockAutofillMetrics)); + } - using AutocheckoutManager::in_autocheckout_flow; - using AutocheckoutManager::autocheckout_offered; - using AutocheckoutManager::MaybeShowAutocheckoutDialog; + const MockAutofillMetrics& metric_logger() const { + return static_cast<const MockAutofillMetrics&>( + AutocheckoutManager::metric_logger()); + } + + using AutocheckoutManager::in_autocheckout_flow; + using AutocheckoutManager::autocheckout_offered; + using AutocheckoutManager::MaybeShowAutocheckoutDialog; }; } // namespace @@ -332,6 +357,9 @@ class AutocheckoutManagerTest : public ChromeRenderViewHostTestHarness { EXPECT_FALSE(autocheckout_manager_->in_autocheckout_flow()); EXPECT_FALSE( autofill_manager_delegate_->request_autocomplete_dialog_open()); + EXPECT_CALL(autocheckout_manager_->metric_logger(), + LogAutocheckoutBubbleMetric( + AutofillMetrics::BUBBLE_COULD_BE_DISPLAYED)).Times(1); autocheckout_manager_->OnLoadedPageMetaData(CreateStartOfFlowMetaData()); // Simulate the user submitting some data via the requestAutocomplete UI. autofill_manager_delegate_->SetUserSuppliedData( @@ -340,6 +368,9 @@ class AutocheckoutManagerTest : public ChromeRenderViewHostTestHarness { content::SSLStatus ssl_status; EXPECT_CALL(*autofill_manager_delegate_, UpdateProgressBar(testing::DoubleEq(1.0/3.0))).Times(1); + EXPECT_CALL(autocheckout_manager_->metric_logger(), + LogAutocheckoutBuyFlowMetric( + AutofillMetrics::AUTOCHECKOUT_BUY_FLOW_STARTED)).Times(1); autocheckout_manager_->MaybeShowAutocheckoutDialog(frame_url, ssl_status, true); @@ -448,6 +479,9 @@ TEST_F(AutocheckoutManagerTest, OnFormsSeenTest) { content::SSLStatus ssl_status; gfx::NativeView native_view; gfx::RectF bounding_box; + EXPECT_CALL(autocheckout_manager_->metric_logger(), + LogAutocheckoutBubbleMetric( + AutofillMetrics::BUBBLE_COULD_BE_DISPLAYED)).Times(1); autocheckout_manager_->OnLoadedPageMetaData(CreateStartOfFlowMetaData()); autocheckout_manager_->MaybeShowAutocheckoutBubble(frame_url, ssl_status, @@ -459,11 +493,28 @@ TEST_F(AutocheckoutManagerTest, OnFormsSeenTest) { EXPECT_FALSE(autocheckout_manager_->autocheckout_offered()); } +TEST_F(AutocheckoutManagerTest, OnClickFailedTest) { + OpenRequestAutocompleteDialog(); + + EXPECT_CALL(*autofill_manager_delegate_, OnAutocheckoutError()).Times(1); + EXPECT_CALL( + autocheckout_manager_->metric_logger(), + LogAutocheckoutBuyFlowMetric( + AutofillMetrics::AUTOCHECKOUT_BUY_FLOW_MISSING_ADVANCE_ELEMENT)) + .Times(1); + autocheckout_manager_->OnClickFailed(MISSING_ADVANCE); + EXPECT_FALSE(autocheckout_manager_->in_autocheckout_flow()); + HideRequestAutocompleteDialog(); +} + TEST_F(AutocheckoutManagerTest, MaybeShowAutocheckoutBubbleTest) { GURL frame_url; content::SSLStatus ssl_status; gfx::NativeView native_view; gfx::RectF bounding_box; + EXPECT_CALL(autocheckout_manager_->metric_logger(), + LogAutocheckoutBubbleMetric( + AutofillMetrics::BUBBLE_COULD_BE_DISPLAYED)).Times(1); autocheckout_manager_->OnLoadedPageMetaData(CreateStartOfFlowMetaData()); // MaybeShowAutocheckoutBubble shows bubble if it has not been shown. autocheckout_manager_->MaybeShowAutocheckoutBubble(frame_url, @@ -488,24 +539,37 @@ TEST_F(AutocheckoutManagerTest, MaybeShowAutocheckoutBubbleTest) { EXPECT_FALSE(autofill_manager_delegate_->request_autocomplete_dialog_open()); } -TEST_F(AutocheckoutManagerTest, OnLoadedPageMetaDataTest) { +TEST_F(AutocheckoutManagerTest, OnLoadedPageMetaDataMissingMetaData) { // Gettting no meta data after any autocheckout page is an error. OpenRequestAutocompleteDialog(); EXPECT_CALL(*autofill_manager_delegate_, OnAutocheckoutError()).Times(1); + EXPECT_CALL( + autocheckout_manager_->metric_logger(), + LogAutocheckoutBuyFlowMetric( + AutofillMetrics::AUTOCHECKOUT_BUY_FLOW_MISSING_FIELDMAPPING)) + .Times(1); autocheckout_manager_->OnLoadedPageMetaData( scoped_ptr<AutocheckoutPageMetaData>()); EXPECT_FALSE(autocheckout_manager_->in_autocheckout_flow()); EXPECT_EQ(0U, process()->sink().message_count()); HideRequestAutocompleteDialog(); +} +TEST_F(AutocheckoutManagerTest, OnLoadedPageMetaDataRepeatedStartPage) { // Getting start page twice in a row is an error. OpenRequestAutocompleteDialog(); EXPECT_CALL(*autofill_manager_delegate_, OnAutocheckoutError()).Times(1); + EXPECT_CALL( + autocheckout_manager_->metric_logger(), + LogAutocheckoutBuyFlowMetric( + AutofillMetrics::AUTOCHECKOUT_BUY_FLOW_CANNOT_PROCEED)).Times(1); autocheckout_manager_->OnLoadedPageMetaData(CreateStartOfFlowMetaData()); EXPECT_FALSE(autocheckout_manager_->in_autocheckout_flow()); EXPECT_EQ(0U, process()->sink().message_count()); HideRequestAutocompleteDialog(); +} +TEST_F(AutocheckoutManagerTest, OnLoadedPageMetaDataRepeatedPage) { // Repeating a page is an error. OpenRequestAutocompleteDialog(); // Go to second page. @@ -515,19 +579,52 @@ TEST_F(AutocheckoutManagerTest, OnLoadedPageMetaDataTest) { EXPECT_TRUE(autocheckout_manager_->in_autocheckout_flow()); CheckFillFormsAndClickIpc(); EXPECT_CALL(*autofill_manager_delegate_, OnAutocheckoutError()).Times(1); + EXPECT_CALL( + autocheckout_manager_->metric_logger(), + LogAutocheckoutBuyFlowMetric( + AutofillMetrics::AUTOCHECKOUT_BUY_FLOW_CANNOT_PROCEED)).Times(1); autocheckout_manager_->OnLoadedPageMetaData(CreateInFlowMetaData()); EXPECT_FALSE(autocheckout_manager_->in_autocheckout_flow()); EXPECT_EQ(0U, process()->sink().message_count()); HideRequestAutocompleteDialog(); +} +TEST_F(AutocheckoutManagerTest, OnLoadedPageMetaDataNotInFlow) { + // Repeating a page is an error. + OpenRequestAutocompleteDialog(); + // Go to second page. + EXPECT_CALL(*autofill_manager_delegate_, + UpdateProgressBar(testing::DoubleEq(2.0/3.0))).Times(1); + autocheckout_manager_->OnLoadedPageMetaData(CreateInFlowMetaData()); + EXPECT_TRUE(autocheckout_manager_->in_autocheckout_flow()); + CheckFillFormsAndClickIpc(); + EXPECT_CALL(*autofill_manager_delegate_, OnAutocheckoutError()).Times(1); + EXPECT_CALL( + autocheckout_manager_->metric_logger(), + LogAutocheckoutBuyFlowMetric( + AutofillMetrics::AUTOCHECKOUT_BUY_FLOW_MISSING_FIELDMAPPING)) + .Times(1); + autocheckout_manager_->OnLoadedPageMetaData(CreateNotInFlowMetaData()); + EXPECT_FALSE(autocheckout_manager_->in_autocheckout_flow()); + EXPECT_EQ(0U, process()->sink().message_count()); + HideRequestAutocompleteDialog(); +} + +TEST_F(AutocheckoutManagerTest, + OnLoadedPageMetaDataShouldNotFillFormsIfNotInFlow) { // If not in flow, OnLoadedPageMetaData does not fill forms. + EXPECT_CALL(autocheckout_manager_->metric_logger(), + LogAutocheckoutBubbleMetric( + AutofillMetrics::BUBBLE_COULD_BE_DISPLAYED)).Times(1); autocheckout_manager_->OnLoadedPageMetaData(CreateStartOfFlowMetaData()); // Go to second page. EXPECT_CALL(*autofill_manager_delegate_, UpdateProgressBar(testing::_)).Times(0); autocheckout_manager_->OnLoadedPageMetaData(CreateInFlowMetaData()); EXPECT_EQ(0U, process()->sink().message_count()); +} +TEST_F(AutocheckoutManagerTest, FullAutocheckoutFlow) { // Test for progression through last page. OpenRequestAutocompleteDialog(); // Go to second page. @@ -538,6 +635,9 @@ TEST_F(AutocheckoutManagerTest, OnLoadedPageMetaDataTest) { CheckFillFormsAndClickIpc(); // Go to third page. EXPECT_CALL(*autofill_manager_delegate_, UpdateProgressBar(1)).Times(1); + EXPECT_CALL(autocheckout_manager_->metric_logger(), + LogAutocheckoutBuyFlowMetric( + AutofillMetrics::AUTOCHECKOUT_BUY_FLOW_SUCCESS)).Times(1); autocheckout_manager_->OnLoadedPageMetaData(CreateEndOfFlowMetaData()); CheckFillFormsAndClickIpc(); EXPECT_FALSE(autocheckout_manager_->in_autocheckout_flow()); @@ -549,6 +649,9 @@ TEST_F(AutocheckoutManagerTest, SinglePageFlow) { EXPECT_FALSE(autocheckout_manager_->in_autocheckout_flow()); EXPECT_FALSE( autofill_manager_delegate_->request_autocomplete_dialog_open()); + EXPECT_CALL(autocheckout_manager_->metric_logger(), + LogAutocheckoutBubbleMetric( + AutofillMetrics::BUBBLE_COULD_BE_DISPLAYED)).Times(1); autocheckout_manager_->OnLoadedPageMetaData(CreateOnePageFlowMetaData()); // Simulate the user submitting some data via the requestAutocomplete UI. autofill_manager_delegate_->SetUserSuppliedData( @@ -557,6 +660,12 @@ TEST_F(AutocheckoutManagerTest, SinglePageFlow) { content::SSLStatus ssl_status; EXPECT_CALL(*autofill_manager_delegate_, UpdateProgressBar(testing::DoubleEq(1))).Times(1); + EXPECT_CALL(autocheckout_manager_->metric_logger(), + LogAutocheckoutBuyFlowMetric( + AutofillMetrics::AUTOCHECKOUT_BUY_FLOW_STARTED)).Times(1); + EXPECT_CALL(autocheckout_manager_->metric_logger(), + LogAutocheckoutBuyFlowMetric( + AutofillMetrics::AUTOCHECKOUT_BUY_FLOW_SUCCESS)).Times(1); autocheckout_manager_->MaybeShowAutocheckoutDialog(frame_url, ssl_status, true); diff --git a/components/autofill/browser/autofill_metrics.cc b/components/autofill/browser/autofill_metrics.cc index 8ced258..9e6671f 100644 --- a/components/autofill/browser/autofill_metrics.cc +++ b/components/autofill/browser/autofill_metrics.cc @@ -336,6 +336,14 @@ void AutofillMetrics::LogAutocheckoutBubbleMetric(BubbleMetric metric) const { UMA_HISTOGRAM_ENUMERATION("Autocheckout.Bubble", metric, NUM_BUBBLE_METRICS); } +void AutofillMetrics::LogAutocheckoutBuyFlowMetric( + AutocheckoutBuyFlowMetric metric) const { + DCHECK_LT(metric, NUM_AUTOCHECKOUT_BUY_FLOW_METRICS); + + UMA_HISTOGRAM_ENUMERATION("Autocheckout.BuyFlow", metric, + NUM_AUTOCHECKOUT_BUY_FLOW_METRICS); +} + void AutofillMetrics::LogCreditCardInfoBarMetric(InfoBarMetric metric) const { DCHECK_LT(metric, NUM_INFO_BAR_METRICS); diff --git a/components/autofill/browser/autofill_metrics.h b/components/autofill/browser/autofill_metrics.h index f218add..5f8f4e4 100644 --- a/components/autofill/browser/autofill_metrics.h +++ b/components/autofill/browser/autofill_metrics.h @@ -18,6 +18,22 @@ class TimeDelta; class AutofillMetrics { public: + // The possible results of an Autocheckout flow. + enum AutocheckoutBuyFlowMetric { + // The user has initated Autocheckout. The baseline metric. + AUTOCHECKOUT_BUY_FLOW_STARTED, + // Autocheckout completed successfully. + AUTOCHECKOUT_BUY_FLOW_SUCCESS, + // Autocheckout failed due to missing server side data. + AUTOCHECKOUT_BUY_FLOW_MISSING_FIELDMAPPING, + // Autocheckout failed due to a missing proceed element. + AUTOCHECKOUT_BUY_FLOW_MISSING_ADVANCE_ELEMENT, + // Autocheckout failed for any number of other reasons, e.g, the proceed + // element click failed, the page numbers were not increasing, etc. + AUTOCHECKOUT_BUY_FLOW_CANNOT_PROCEED, + NUM_AUTOCHECKOUT_BUY_FLOW_METRICS + }; + // The success or failure of Autocheckout. enum AutocheckoutCompletionStatus { AUTOCHECKOUT_FAILED, // The user canceled out of the dialog after @@ -28,10 +44,12 @@ class AutofillMetrics { // The action a user took to dismiss a bubble. enum BubbleMetric { - BUBBLE_CREATED = 0, // The bubble was created. - BUBBLE_ACCEPTED, // The user accepted, i.e. confirmed, the bubble. - BUBBLE_DISMISSED, // The user dismissed the bubble. - BUBBLE_IGNORED, // The user did not interact with the bubble. + BUBBLE_CREATED = 0, // The bubble was created. + BUBBLE_ACCEPTED, // The user accepted, i.e. confirmed, the + // bubble. + BUBBLE_DISMISSED, // The user dismissed the bubble. + BUBBLE_IGNORED, // The user did not interact with the bubble. + BUBBLE_COULD_BE_DISPLAYED, // The bubble could be displayed. NUM_BUBBLE_METRICS, }; @@ -273,6 +291,10 @@ class AutofillMetrics { // Logs how the user interacted with the Autocheckout bubble. virtual void LogAutocheckoutBubbleMetric(BubbleMetric metric) const; + // Logs the result of an Autocheckout buy flow. + virtual void LogAutocheckoutBuyFlowMetric( + AutocheckoutBuyFlowMetric metric) const; + virtual void LogCreditCardInfoBarMetric(InfoBarMetric metric) const; virtual void LogDeveloperEngagementMetric( |