Commit 321723b0 authored by Gang Wu's avatar Gang Wu Committed by Commit Bot

[Feed] implement search history service to check if the url is visited

Also change the feed_logging_metrics.h into class for future features,
Like hook up all the UMA with Feed internal page.

Bug: 867767

Change-Id: I5559207df16d9c431208bd65cf20326a22116202
Reviewed-on: https://chromium-review.googlesource.com/c/1258250
Commit-Queue: Gang Wu <gangwu@chromium.org>
Reviewed-by: default avatarSky Malice <skym@chromium.org>
Cr-Commit-Position: refs/heads/master@{#596389}
parent c262a105
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
#include "ui/base/mojo/window_open_disposition.mojom.h" #include "ui/base/mojo/window_open_disposition.mojom.h"
namespace feed { namespace feed {
namespace metrics {
namespace { namespace {
...@@ -70,16 +69,23 @@ int ToUMAScore(float score) { ...@@ -70,16 +69,23 @@ int ToUMAScore(float score) {
} // namespace } // namespace
void OnPageShown(const int suggestions_count) { FeedLoggingMetrics::FeedLoggingMetrics(
HistoryURLCheckCallback history_url_check_callback)
: history_url_check_callback_(std::move(history_url_check_callback)),
weak_ptr_factory_(this) {}
FeedLoggingMetrics::~FeedLoggingMetrics() = default;
void FeedLoggingMetrics::OnPageShown(const int suggestions_count) {
UMA_HISTOGRAM_EXACT_LINEAR( UMA_HISTOGRAM_EXACT_LINEAR(
"NewTabPage.ContentSuggestions.CountOnNtpOpenedIfVisible", "NewTabPage.ContentSuggestions.CountOnNtpOpenedIfVisible",
suggestions_count, kMaxSuggestionsTotal); suggestions_count, kMaxSuggestionsTotal);
} }
void OnSuggestionShown(int position, void FeedLoggingMetrics::OnSuggestionShown(int position,
base::Time publish_date, base::Time publish_date,
float score, float score,
base::Time fetch_date) { base::Time fetch_date) {
UMA_HISTOGRAM_EXACT_LINEAR("NewTabPage.ContentSuggestions.Shown", position, UMA_HISTOGRAM_EXACT_LINEAR("NewTabPage.ContentSuggestions.Shown", position,
kMaxSuggestionsTotal); kMaxSuggestionsTotal);
...@@ -106,10 +112,10 @@ void OnSuggestionShown(int position, ...@@ -106,10 +112,10 @@ void OnSuggestionShown(int position,
} }
} }
void OnSuggestionOpened(int position, void FeedLoggingMetrics::OnSuggestionOpened(int position,
base::Time publish_date, base::Time publish_date,
float score, float score,
WindowOpenDisposition disposition) { WindowOpenDisposition disposition) {
UMA_HISTOGRAM_EXACT_LINEAR("NewTabPage.ContentSuggestions.Opened", position, UMA_HISTOGRAM_EXACT_LINEAR("NewTabPage.ContentSuggestions.Opened", position,
kMaxSuggestionsTotal); kMaxSuggestionsTotal);
...@@ -134,9 +140,9 @@ void OnSuggestionOpened(int position, ...@@ -134,9 +140,9 @@ void OnSuggestionOpened(int position,
base::RecordAction(base::UserMetricsAction("Suggestions.Content.Opened")); base::RecordAction(base::UserMetricsAction("Suggestions.Content.Opened"));
} }
void OnSuggestionMenuOpened(int position, void FeedLoggingMetrics::OnSuggestionMenuOpened(int position,
base::Time publish_date, base::Time publish_date,
float score) { float score) {
UMA_HISTOGRAM_EXACT_LINEAR("NewTabPage.ContentSuggestions.MenuOpened", UMA_HISTOGRAM_EXACT_LINEAR("NewTabPage.ContentSuggestions.MenuOpened",
position, kMaxSuggestionsTotal); position, kMaxSuggestionsTotal);
...@@ -150,23 +156,19 @@ void OnSuggestionMenuOpened(int position, ...@@ -150,23 +156,19 @@ void OnSuggestionMenuOpened(int position,
ToUMAScore(score), 11); ToUMAScore(score), 11);
} }
void OnSuggestionDismissed(int position, bool visited) { void FeedLoggingMetrics::OnSuggestionDismissed(int position, const GURL& url) {
if (visited) { history_url_check_callback_.Run(
UMA_HISTOGRAM_EXACT_LINEAR("NewTabPage.ContentSuggestions.DismissedVisited", url, base::BindOnce(&FeedLoggingMetrics::CheckURLVisitedDone,
position, kMaxSuggestionsTotal); weak_ptr_factory_.GetWeakPtr(), position));
} else {
UMA_HISTOGRAM_EXACT_LINEAR(
"NewTabPage.ContentSuggestions.DismissedUnvisited", position,
kMaxSuggestionsTotal);
}
} }
void OnSuggestionArticleVisited(base::TimeDelta visit_time) { void FeedLoggingMetrics::OnSuggestionArticleVisited(
base::TimeDelta visit_time) {
base::UmaHistogramLongTimes( base::UmaHistogramLongTimes(
"NewTabPage.ContentSuggestions.VisitDuration.Articles", visit_time); "NewTabPage.ContentSuggestions.VisitDuration.Articles", visit_time);
} }
void OnMoreButtonShown(int position) { void FeedLoggingMetrics::OnMoreButtonShown(int position) {
// The "more" card can appear in addition to the actual suggestions, so add // The "more" card can appear in addition to the actual suggestions, so add
// one extra bucket to this histogram. // one extra bucket to this histogram.
UMA_HISTOGRAM_EXACT_LINEAR( UMA_HISTOGRAM_EXACT_LINEAR(
...@@ -174,7 +176,7 @@ void OnMoreButtonShown(int position) { ...@@ -174,7 +176,7 @@ void OnMoreButtonShown(int position) {
kMaxSuggestionsForArticle + 1); kMaxSuggestionsForArticle + 1);
} }
void OnMoreButtonClicked(int position) { void FeedLoggingMetrics::OnMoreButtonClicked(int position) {
// The "more" card can appear in addition to the actual suggestions, so add // The "more" card can appear in addition to the actual suggestions, so add
// one extra bucket to this histogram. // one extra bucket to this histogram.
UMA_HISTOGRAM_EXACT_LINEAR( UMA_HISTOGRAM_EXACT_LINEAR(
...@@ -182,5 +184,15 @@ void OnMoreButtonClicked(int position) { ...@@ -182,5 +184,15 @@ void OnMoreButtonClicked(int position) {
kMaxSuggestionsForArticle + 1); kMaxSuggestionsForArticle + 1);
} }
} // namespace metrics void FeedLoggingMetrics::CheckURLVisitedDone(int position, bool visited) {
if (visited) {
UMA_HISTOGRAM_EXACT_LINEAR("NewTabPage.ContentSuggestions.DismissedVisited",
position, kMaxSuggestionsTotal);
} else {
UMA_HISTOGRAM_EXACT_LINEAR(
"NewTabPage.ContentSuggestions.DismissedUnvisited", position,
kMaxSuggestionsTotal);
}
}
} // namespace feed } // namespace feed
...@@ -5,6 +5,11 @@ ...@@ -5,6 +5,11 @@
#ifndef COMPONENTS_FEED_CORE_FEED_LOGGING_METRICS_H_ #ifndef COMPONENTS_FEED_CORE_FEED_LOGGING_METRICS_H_
#define COMPONENTS_FEED_CORE_FEED_LOGGING_METRICS_H_ #define COMPONENTS_FEED_CORE_FEED_LOGGING_METRICS_H_
#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "url/gurl.h"
namespace base { namespace base {
class Time; class Time;
class TimeDelta; class TimeDelta;
...@@ -13,35 +18,59 @@ class TimeDelta; ...@@ -13,35 +18,59 @@ class TimeDelta;
enum class WindowOpenDisposition; enum class WindowOpenDisposition;
namespace feed { namespace feed {
namespace metrics {
// |suggestions_count| contains how many cards show to users. It does not depend // FeedLoggingMetrics is a central place to report all the UMA metrics for Feed.
// on whether the user actually saw the cards. class FeedLoggingMetrics {
void OnPageShown(const int suggestions_count); public:
// Return whether the URL is visited when calling checking URL visited.
using CheckURLVisitCallback = base::OnceCallback<void(bool)>;
// Calling this callback when need to check whether url is visited, and will
// tell CheckURLVisitCallback the result.
using HistoryURLCheckCallback =
base::RepeatingCallback<void(GURL, CheckURLVisitCallback)>;
explicit FeedLoggingMetrics(HistoryURLCheckCallback callback);
~FeedLoggingMetrics();
// |suggestions_count| contains how many cards show to users. It does not
// depend on whether the user actually saw the cards.
void OnPageShown(const int suggestions_count);
// Should only be called once per NTP for each suggestion.
void OnSuggestionShown(int position,
base::Time publish_date,
float score,
base::Time fetch_date);
void OnSuggestionOpened(int position,
base::Time publish_date,
float score,
WindowOpenDisposition disposition);
void OnSuggestionMenuOpened(int position,
base::Time publish_date,
float score);
void OnSuggestionDismissed(int position, const GURL& url);
// Should only be called once per NTP for each suggestion. void OnSuggestionArticleVisited(base::TimeDelta visit_time);
void OnSuggestionShown(int position,
base::Time publish_date,
float score,
base::Time fetch_date);
void OnSuggestionOpened(int position, // Should only be called once per NTP for each "more" button.
base::Time publish_date, void OnMoreButtonShown(int position);
float score,
WindowOpenDisposition disposition);
void OnSuggestionMenuOpened(int position, base::Time publish_date, float score); void OnMoreButtonClicked(int position);
void OnSuggestionDismissed(int position, bool visited); private:
void CheckURLVisitedDone(int position, bool visited);
void OnSuggestionArticleVisited(base::TimeDelta visit_time); const HistoryURLCheckCallback history_url_check_callback_;
// Should only be called once per NTP for each "more" button. base::WeakPtrFactory<FeedLoggingMetrics> weak_ptr_factory_;
void OnMoreButtonShown(int position);
void OnMoreButtonClicked(int position); DISALLOW_COPY_AND_ASSIGN(FeedLoggingMetrics);
};
} // namespace metrics
} // namespace feed } // namespace feed
#endif // COMPONENTS_FEED_CORE_FEED_LOGGING_METRICS_H_ #endif // COMPONENTS_FEED_CORE_FEED_LOGGING_METRICS_H_
// Copyright 2017 The Chromium Authors. All rights reserved. // Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
...@@ -11,9 +11,10 @@ ...@@ -11,9 +11,10 @@
#include "ui/base/mojo/window_open_disposition.mojom.h" #include "ui/base/mojo/window_open_disposition.mojom.h"
namespace feed { namespace feed {
namespace metrics {
namespace { namespace {
GURL VISITED_URL("http://visited_url.com");
using testing::ElementsAre; using testing::ElementsAre;
using testing::IsEmpty; using testing::IsEmpty;
...@@ -28,21 +29,49 @@ enum FeedActionType { ...@@ -28,21 +29,49 @@ enum FeedActionType {
DOWNLOAD = 5, DOWNLOAD = 5,
}; };
TEST(FeedLoggingMetricsTest, ShouldLogOnSuggestionsShown) { void CheckURLVisit(GURL url,
FeedLoggingMetrics::CheckURLVisitCallback callback) {
if (url == VISITED_URL) {
std::move(callback).Run(true);
} else {
std::move(callback).Run(false);
}
}
} // namespace
class FeedLoggingMetricsTest : public testing::Test {
public:
FeedLoggingMetricsTest() {
feed_logging_metrics_ = std::make_unique<FeedLoggingMetrics>(
base::BindRepeating(&CheckURLVisit));
}
FeedLoggingMetrics* feed_logging_metrics() {
return feed_logging_metrics_.get();
}
private:
std::unique_ptr<FeedLoggingMetrics> feed_logging_metrics_;
DISALLOW_COPY_AND_ASSIGN(FeedLoggingMetricsTest);
};
TEST_F(FeedLoggingMetricsTest, ShouldLogOnSuggestionsShown) {
base::HistogramTester histogram_tester; base::HistogramTester histogram_tester;
OnSuggestionShown(/*position=*/1, base::Time::Now(), feed_logging_metrics()->OnSuggestionShown(
/*score=*/0.01f, /*position=*/1, base::Time::Now(),
base::Time::Now() - base::TimeDelta::FromHours(2)); /*score=*/0.01f, base::Time::Now() - base::TimeDelta::FromHours(2));
// Test corner cases for score. // Test corner cases for score.
OnSuggestionShown(/*position=*/2, base::Time::Now(), feed_logging_metrics()->OnSuggestionShown(
/*score=*/0.0f, /*position=*/2, base::Time::Now(),
base::Time::Now() - base::TimeDelta::FromHours(2)); /*score=*/0.0f, base::Time::Now() - base::TimeDelta::FromHours(2));
OnSuggestionShown(/*position=*/3, base::Time::Now(), feed_logging_metrics()->OnSuggestionShown(
/*score=*/1.0f, /*position=*/3, base::Time::Now(),
base::Time::Now() - base::TimeDelta::FromHours(2)); /*score=*/1.0f, base::Time::Now() - base::TimeDelta::FromHours(2));
OnSuggestionShown(/*position=*/4, base::Time::Now(), feed_logging_metrics()->OnSuggestionShown(
/*score=*/8.0f, /*position=*/4, base::Time::Now(),
base::Time::Now() - base::TimeDelta::FromHours(2)); /*score=*/8.0f, base::Time::Now() - base::TimeDelta::FromHours(2));
EXPECT_THAT( EXPECT_THAT(
histogram_tester.GetAllSamples("NewTabPage.ContentSuggestions.Shown"), histogram_tester.GetAllSamples("NewTabPage.ContentSuggestions.Shown"),
...@@ -59,24 +88,28 @@ TEST(FeedLoggingMetricsTest, ShouldLogOnSuggestionsShown) { ...@@ -59,24 +88,28 @@ TEST(FeedLoggingMetricsTest, ShouldLogOnSuggestionsShown) {
base::Bucket(/*min=*/11, /*count=*/1))); base::Bucket(/*min=*/11, /*count=*/1)));
} }
TEST(FeedLoggingMetricsTest, ShouldLogOnPageShown) { TEST_F(FeedLoggingMetricsTest, ShouldLogOnPageShown) {
base::HistogramTester histogram_tester; base::HistogramTester histogram_tester;
OnPageShown(/*content_count=*/10); feed_logging_metrics()->OnPageShown(/*content_count=*/10);
EXPECT_THAT(histogram_tester.GetAllSamples( EXPECT_THAT(histogram_tester.GetAllSamples(
"NewTabPage.ContentSuggestions.CountOnNtpOpenedIfVisible"), "NewTabPage.ContentSuggestions.CountOnNtpOpenedIfVisible"),
ElementsAre(base::Bucket(/*min=*/10, /*count=*/1))); ElementsAre(base::Bucket(/*min=*/10, /*count=*/1)));
} }
TEST(FeedLoggingMetricsTest, ShouldLogPrefetchedSuggestionsWhenOpened) { TEST_F(FeedLoggingMetricsTest, ShouldLogPrefetchedSuggestionsWhenOpened) {
base::HistogramTester histogram_tester; base::HistogramTester histogram_tester;
OnSuggestionOpened(/*position=*/11, base::Time::Now(), feed_logging_metrics()->OnSuggestionOpened(
/*score=*/1.0f, WindowOpenDisposition::CURRENT_TAB); /*position=*/11, base::Time::Now(),
OnSuggestionOpened(/*position=*/13, base::Time::Now(), /*score=*/1.0f, WindowOpenDisposition::CURRENT_TAB);
/*score=*/1.0f, WindowOpenDisposition::CURRENT_TAB); feed_logging_metrics()->OnSuggestionOpened(
OnSuggestionOpened(/*position=*/15, base::Time::Now(), /*position=*/13, base::Time::Now(),
/*score=*/1.0f, WindowOpenDisposition::CURRENT_TAB); /*score=*/1.0f, WindowOpenDisposition::CURRENT_TAB);
OnSuggestionOpened(/*position=*/23, base::Time::Now(), feed_logging_metrics()->OnSuggestionOpened(
/*score=*/1.0f, WindowOpenDisposition::CURRENT_TAB); /*position=*/15, base::Time::Now(),
/*score=*/1.0f, WindowOpenDisposition::CURRENT_TAB);
feed_logging_metrics()->OnSuggestionOpened(
/*position=*/23, base::Time::Now(),
/*score=*/1.0f, WindowOpenDisposition::CURRENT_TAB);
EXPECT_THAT( EXPECT_THAT(
histogram_tester.GetAllSamples("NewTabPage.ContentSuggestions.Opened"), histogram_tester.GetAllSamples("NewTabPage.ContentSuggestions.Opened"),
...@@ -86,6 +119,21 @@ TEST(FeedLoggingMetricsTest, ShouldLogPrefetchedSuggestionsWhenOpened) { ...@@ -86,6 +119,21 @@ TEST(FeedLoggingMetricsTest, ShouldLogPrefetchedSuggestionsWhenOpened) {
base::Bucket(/*min=*/23, /*count=*/1))); base::Bucket(/*min=*/23, /*count=*/1)));
} }
} // namespace TEST_F(FeedLoggingMetricsTest, ShouldLogOnSuggestionDismissedIfVisited) {
} // namespace metrics base::HistogramTester histogram_tester;
feed_logging_metrics()->OnSuggestionDismissed(/*position=*/10, VISITED_URL);
EXPECT_THAT(histogram_tester.GetAllSamples(
"NewTabPage.ContentSuggestions.DismissedVisited"),
ElementsAre(base::Bucket(/*min=*/10, /*count=*/1)));
}
TEST_F(FeedLoggingMetricsTest, ShouldLogOnSuggestionDismissedIfNotVisited) {
base::HistogramTester histogram_tester;
feed_logging_metrics()->OnSuggestionDismissed(/*position=*/10,
GURL("http://non_visited.com"));
EXPECT_THAT(histogram_tester.GetAllSamples(
"NewTabPage.ContentSuggestions.DismissedVisited"),
IsEmpty());
}
} // namespace feed } // namespace feed
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment