Commit 8984cac9 authored by Gang Wu's avatar Gang Wu Committed by Commit Bot

[Feed] Copy metrics code from ntp_snippets to Feed

Copy over the files
components/ntp_snippets/content_suggestions_metrics.cc
components/ntp_snippets/content_suggestions_metrics.h
to
components/feed/core/feed_logging_metrics.cc
components/feed/core/feed_logging_metrics.h



Bug: 888047

Change-Id: I7f8baff84c6d23c80f1d079b6f0e33aa69c9a2c4
Reviewed-on: https://chromium-review.googlesource.com/c/1235314Reviewed-by: default avatarSky Malice <skym@chromium.org>
Reviewed-by: default avatarccameron <ccameron@chromium.org>
Commit-Queue: Gang Wu <gangwu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#595923}
parent 1b8b5152
......@@ -18,6 +18,7 @@ include_rules = [
"+services/network/public/mojom",
"+services/network/test",
"+third_party/zlib/google",
"+ui/base/mojo",
"+ui/gfx/geometry",
"+ui/gfx/image",
]
......@@ -26,6 +26,8 @@ source_set("feed_core") {
"feed_journal_mutation.h",
"feed_journal_operation.cc",
"feed_journal_operation.h",
"feed_logging_metrics.cc",
"feed_logging_metrics.h",
"feed_networking_host.cc",
"feed_networking_host.h",
"feed_scheduler_host.cc",
......@@ -47,6 +49,7 @@ source_set("feed_core") {
"//components/image_fetcher/core:core",
"//components/leveldb_proto",
"//net",
"//ui/base/mojo:mojo",
]
deps = [
......@@ -81,6 +84,7 @@ source_set("core_unit_tests") {
"feed_image_manager_unittest.cc",
"feed_journal_database_unittest.cc",
"feed_journal_mutation_unittest.cc",
"feed_logging_metrics_unittest.cc",
"feed_networking_host_unittest.cc",
"feed_scheduler_host_unittest.cc",
"refresh_throttler_unittest.cc",
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/feed/core/feed_logging_metrics.h"
#include <cmath>
#include <string>
#include <type_traits>
#include "base/metrics/histogram.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/metrics/user_metrics.h"
#include "base/strings/stringprintf.h"
#include "base/time/time.h"
#include "ui/base/mojo/window_open_disposition.mojom.h"
namespace feed {
namespace metrics {
namespace {
// The constant integers(bucket sizes) and strings(UMA names) in this file need
// matching with Zine's in the file
// components/ntp_snippets/content_suggestions_metrics.cc. The purpose to have
// identical bucket sizes and names with Zine is for comparing Feed with Zine
// easily. After Zine is deprecated, we can change the values if we needed.
const int kMaxSuggestionsTotal = 50;
// Keep in sync with MAX_SUGGESTIONS_PER_SECTION in NewTabPageUma.java.
const int kMaxSuggestionsForArticle = 20;
const char kHistogramArticlesUsageTimeLocal[] =
"NewTabPage.ContentSuggestions.UsageTimeLocal";
// Records ContentSuggestions usage. Therefore the day is sliced into 20min
// buckets. Depending on the current local time the count of the corresponding
// bucket is increased.
void RecordContentSuggestionsUsage() {
const int kBucketSizeMins = 20;
const int kNumBuckets = 24 * 60 / kBucketSizeMins;
base::Time::Exploded now_exploded;
base::Time::Now().LocalExplode(&now_exploded);
int bucket = (now_exploded.hour * 60 + now_exploded.minute) / kBucketSizeMins;
const char* kWeekdayNames[] = {"Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday"};
std::string histogram_name(
base::StringPrintf("%s.%s", kHistogramArticlesUsageTimeLocal,
kWeekdayNames[now_exploded.day_of_week]));
base::UmaHistogramExactLinear(histogram_name, bucket, kNumBuckets);
UMA_HISTOGRAM_EXACT_LINEAR(kHistogramArticlesUsageTimeLocal, bucket,
kNumBuckets);
base::RecordAction(
base::UserMetricsAction("NewTabPage_ContentSuggestions_ArticlesUsage"));
}
int ToUMAScore(float score) {
// Scores are typically reported in a range of (0,1]. As UMA does not support
// floats, we put them on a discrete scale of [1,10]. We keep the extra bucket
// 11 for unexpected over-flows as we want to distinguish them from scores
// close to 1. For instance, the discrete value 1 represents score values
// within (0.0, 0.1].
return ceil(score * 10);
}
} // namespace
void OnPageShown(const int suggestions_count) {
UMA_HISTOGRAM_EXACT_LINEAR(
"NewTabPage.ContentSuggestions.CountOnNtpOpenedIfVisible",
suggestions_count, kMaxSuggestionsTotal);
}
void OnSuggestionShown(int position,
base::Time publish_date,
float score,
base::Time fetch_date) {
UMA_HISTOGRAM_EXACT_LINEAR("NewTabPage.ContentSuggestions.Shown", position,
kMaxSuggestionsTotal);
base::TimeDelta age = base::Time::Now() - publish_date;
UMA_HISTOGRAM_CUSTOM_TIMES("NewTabPage.ContentSuggestions.ShownAge.Articles",
age, base::TimeDelta::FromSeconds(1),
base::TimeDelta::FromDays(7), 100);
UMA_HISTOGRAM_EXACT_LINEAR(
"NewTabPage.ContentSuggestions.ShownScoreNormalized.Articles",
ToUMAScore(score), 11);
// Records the time since the fetch time of the displayed snippet.
UMA_HISTOGRAM_CUSTOM_TIMES(
"NewTabPage.ContentSuggestions.TimeSinceSuggestionFetched",
base::Time::Now() - fetch_date, base::TimeDelta::FromSeconds(1),
base::TimeDelta::FromDays(7),
/*bucket_count=*/100);
// When the first of the articles suggestions is shown, then we count this as
// a single usage of content suggestions.
if (position == 0) {
RecordContentSuggestionsUsage();
}
}
void OnSuggestionOpened(int position,
base::Time publish_date,
float score,
WindowOpenDisposition disposition) {
UMA_HISTOGRAM_EXACT_LINEAR("NewTabPage.ContentSuggestions.Opened", position,
kMaxSuggestionsTotal);
base::TimeDelta age = base::Time::Now() - publish_date;
UMA_HISTOGRAM_CUSTOM_TIMES("NewTabPage.ContentSuggestions.OpenedAge.Articles",
age, base::TimeDelta::FromSeconds(1),
base::TimeDelta::FromDays(7), 100);
UMA_HISTOGRAM_EXACT_LINEAR(
"NewTabPage.ContentSuggestions.OpenedScoreNormalized.Articles",
ToUMAScore(score), 11);
// We use WindowOpenDisposition::MAX_VALUE + 1 for |value_max| since MAX_VALUE
// itself is a valid (and used) enum value.
UMA_HISTOGRAM_EXACT_LINEAR(
"NewTabPage.ContentSuggestions.OpenDisposition.Articles",
static_cast<int>(disposition),
static_cast<int>(WindowOpenDisposition::MAX_VALUE) + 1);
RecordContentSuggestionsUsage();
base::RecordAction(base::UserMetricsAction("Suggestions.Content.Opened"));
}
void OnSuggestionMenuOpened(int position,
base::Time publish_date,
float score) {
UMA_HISTOGRAM_EXACT_LINEAR("NewTabPage.ContentSuggestions.MenuOpened",
position, kMaxSuggestionsTotal);
base::TimeDelta age = base::Time::Now() - publish_date;
UMA_HISTOGRAM_CUSTOM_TIMES(
"NewTabPage.ContentSuggestions.MenuOpenedAge.Articles", age,
base::TimeDelta::FromSeconds(1), base::TimeDelta::FromDays(7), 100);
UMA_HISTOGRAM_EXACT_LINEAR(
"NewTabPage.ContentSuggestions.MenuOpenedScoreNormalized.Articles",
ToUMAScore(score), 11);
}
void OnSuggestionDismissed(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);
}
}
void OnSuggestionArticleVisited(base::TimeDelta visit_time) {
base::UmaHistogramLongTimes(
"NewTabPage.ContentSuggestions.VisitDuration.Articles", visit_time);
}
void OnMoreButtonShown(int position) {
// The "more" card can appear in addition to the actual suggestions, so add
// one extra bucket to this histogram.
UMA_HISTOGRAM_EXACT_LINEAR(
"NewTabPage.ContentSuggestions.MoreButtonShown.Articles", position,
kMaxSuggestionsForArticle + 1);
}
void OnMoreButtonClicked(int position) {
// The "more" card can appear in addition to the actual suggestions, so add
// one extra bucket to this histogram.
UMA_HISTOGRAM_EXACT_LINEAR(
"NewTabPage.ContentSuggestions.MoreButtonClicked.Articles", position,
kMaxSuggestionsForArticle + 1);
}
} // namespace metrics
} // namespace feed
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_FEED_CORE_FEED_LOGGING_METRICS_H_
#define COMPONENTS_FEED_CORE_FEED_LOGGING_METRICS_H_
namespace base {
class Time;
class TimeDelta;
} // namespace base
enum class WindowOpenDisposition;
namespace feed {
namespace metrics {
// |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, bool visited);
void OnSuggestionArticleVisited(base::TimeDelta visit_time);
// Should only be called once per NTP for each "more" button.
void OnMoreButtonShown(int position);
void OnMoreButtonClicked(int position);
} // namespace metrics
} // namespace feed
#endif // COMPONENTS_FEED_CORE_FEED_LOGGING_METRICS_H_
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/feed/core/feed_logging_metrics.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/time/time.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/mojo/window_open_disposition.mojom.h"
namespace feed {
namespace metrics {
namespace {
using testing::ElementsAre;
using testing::IsEmpty;
// This needs to keep in sync with ActionType in third_party/feed/src/src/main/
// java/com/google/android/libraries/feed/host/logging/ActionType.java.
enum FeedActionType {
UNKNOWN = -1,
OPEN_URL = 1,
OPEN_URL_INCOGNITO = 2,
OPEN_URL_NEW_WINDOW = 3,
OPEN_URL_NEW_TAB = 4,
DOWNLOAD = 5,
};
TEST(FeedLoggingMetricsTest, ShouldLogOnSuggestionsShown) {
base::HistogramTester histogram_tester;
OnSuggestionShown(/*position=*/1, base::Time::Now(),
/*score=*/0.01f,
base::Time::Now() - base::TimeDelta::FromHours(2));
// Test corner cases for score.
OnSuggestionShown(/*position=*/2, base::Time::Now(),
/*score=*/0.0f,
base::Time::Now() - base::TimeDelta::FromHours(2));
OnSuggestionShown(/*position=*/3, base::Time::Now(),
/*score=*/1.0f,
base::Time::Now() - base::TimeDelta::FromHours(2));
OnSuggestionShown(/*position=*/4, base::Time::Now(),
/*score=*/8.0f,
base::Time::Now() - base::TimeDelta::FromHours(2));
EXPECT_THAT(
histogram_tester.GetAllSamples("NewTabPage.ContentSuggestions.Shown"),
ElementsAre(base::Bucket(/*min=*/1, /*count=*/1),
base::Bucket(/*min=*/2, /*count=*/1),
base::Bucket(/*min=*/3, /*count=*/1),
base::Bucket(/*min=*/4, /*count=*/1)));
EXPECT_THAT(
histogram_tester.GetAllSamples(
"NewTabPage.ContentSuggestions.ShownScoreNormalized.Articles"),
ElementsAre(base::Bucket(/*min=*/0, /*count=*/1),
base::Bucket(/*min=*/1, /*count=*/1),
base::Bucket(/*min=*/10, /*count=*/1),
base::Bucket(/*min=*/11, /*count=*/1)));
}
TEST(FeedLoggingMetricsTest, ShouldLogOnPageShown) {
base::HistogramTester histogram_tester;
OnPageShown(/*content_count=*/10);
EXPECT_THAT(histogram_tester.GetAllSamples(
"NewTabPage.ContentSuggestions.CountOnNtpOpenedIfVisible"),
ElementsAre(base::Bucket(/*min=*/10, /*count=*/1)));
}
TEST(FeedLoggingMetricsTest, ShouldLogPrefetchedSuggestionsWhenOpened) {
base::HistogramTester histogram_tester;
OnSuggestionOpened(/*position=*/11, base::Time::Now(),
/*score=*/1.0f, WindowOpenDisposition::CURRENT_TAB);
OnSuggestionOpened(/*position=*/13, base::Time::Now(),
/*score=*/1.0f, WindowOpenDisposition::CURRENT_TAB);
OnSuggestionOpened(/*position=*/15, base::Time::Now(),
/*score=*/1.0f, WindowOpenDisposition::CURRENT_TAB);
OnSuggestionOpened(/*position=*/23, base::Time::Now(),
/*score=*/1.0f, WindowOpenDisposition::CURRENT_TAB);
EXPECT_THAT(
histogram_tester.GetAllSamples("NewTabPage.ContentSuggestions.Opened"),
ElementsAre(base::Bucket(/*min=*/11, /*count=*/1),
base::Bucket(/*min=*/13, /*count=*/1),
base::Bucket(/*min=*/15, /*count=*/1),
base::Bucket(/*min=*/23, /*count=*/1)));
}
} // namespace
} // namespace metrics
} // 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