diff options
Diffstat (limited to 'chromium/components/feed/core/feed_logging_metrics.cc')
-rw-r--r-- | chromium/components/feed/core/feed_logging_metrics.cc | 195 |
1 files changed, 180 insertions, 15 deletions
diff --git a/chromium/components/feed/core/feed_logging_metrics.cc b/chromium/components/feed/core/feed_logging_metrics.cc index 9b83b0aafb3..03989b12cfc 100644 --- a/chromium/components/feed/core/feed_logging_metrics.cc +++ b/chromium/components/feed/core/feed_logging_metrics.cc @@ -8,6 +8,7 @@ #include <string> #include <type_traits> +#include "base/bind.h" #include "base/metrics/histogram.h" #include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" @@ -27,7 +28,11 @@ namespace { // 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. +// Constants used as max sample sizes for histograms. +const int kMaxContentCount = 50; +const int kMaxFailureCount = 10; const int kMaxSuggestionsTotal = 50; +const int kMaxTokenCount = 10; // Keep in sync with MAX_SUGGESTIONS_PER_SECTION in NewTabPageUma.java. const int kMaxSuggestionsForArticle = 20; @@ -35,6 +40,42 @@ const int kMaxSuggestionsForArticle = 20; const char kHistogramArticlesUsageTimeLocal[] = "NewTabPage.ContentSuggestions.UsageTimeLocal"; +// Values correspond to +// third_party/feed/src/src/main/java/com/google/android/libraries/feed/host/ +// logging/SpinnerType.java, enums.xml and histograms.xml. +// These values are persisted to logs. Entries should not be renumbered and +// numeric values should never be reused. +enum class SpinnerType { + KInitialLoad = 1, + KZeroStateRefresh = 2, + KMoreButton = 3, + KSyntheticToken = 4, + KInfiniteFeed = 5, + kMaxValue = KInfiniteFeed +}; + +// Each suffix here should correspond to an entry under histogram suffix +// ContentSuggestionCategory in histograms.xml. +std::string GetSpinnerTypeSuffix(SpinnerType spinner_type) { + switch (spinner_type) { + case SpinnerType::KInitialLoad: + return "InitialLoad"; + case SpinnerType::KZeroStateRefresh: + return "ZeroStateRefresh"; + case SpinnerType::KMoreButton: + return "MoreButton"; + case SpinnerType::KSyntheticToken: + return "SyntheticToken"; + case SpinnerType::KInfiniteFeed: + return "InfiniteFeed"; + } + + // TODO(https://crbug.com/935602): Handle new values when adding new values on + // java side. + NOTREACHED(); + return std::string(); +} + // 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. @@ -51,6 +92,7 @@ void RecordContentSuggestionsUsage(base::Time now) { std::string histogram_name( base::StringPrintf("%s.%s", kHistogramArticlesUsageTimeLocal, kWeekdayNames[now_exploded.day_of_week])); + // Since the |histogram_name| is dynamic, we can't use the regular macro. base::UmaHistogramExactLinear(histogram_name, bucket, kNumBuckets); UMA_HISTOGRAM_EXACT_LINEAR(kHistogramArticlesUsageTimeLocal, bucket, kNumBuckets); @@ -76,6 +118,37 @@ void RecordSuggestionPageVisited(bool return_to_ntp) { base::RecordAction(base::UserMetricsAction("MobileNTP.Snippets.VisitEnd")); } +void RecordUndoableActionUMA(const std::string& histogram_base, + int position, + bool committed) { + std::string histogram_name = + histogram_base + (committed ? ".Commit" : ".Undo"); + + // Since the |histogram_name| is dynamic, we can't use the regular macro. + base::UmaHistogramExactLinear(histogram_name, position, kMaxSuggestionsTotal); +} + +void CheckURLVisitedDone(int position, bool committed, bool visited) { + if (visited) { + RecordUndoableActionUMA("NewTabPage.ContentSuggestions.DismissedVisited", + position, committed); + } else { + RecordUndoableActionUMA("NewTabPage.ContentSuggestions.DismissedUnvisited", + position, committed); + } +} + +void RecordSpinnerTimeUMA(const char* base_name, + base::TimeDelta time, + int spinner_type) { + SpinnerType type = static_cast<SpinnerType>(spinner_type); + std::string suffix = GetSpinnerTypeSuffix(type); + std::string histogram_name( + base::StringPrintf("%s.%s", base_name, suffix.c_str())); + base::UmaHistogramTimes(histogram_name, time); + base::UmaHistogramTimes(base_name, time); +} + } // namespace FeedLoggingMetrics::FeedLoggingMetrics( @@ -178,10 +251,11 @@ void FeedLoggingMetrics::OnSuggestionMenuOpened(int position, ToUMAScore(score), 11); } -void FeedLoggingMetrics::OnSuggestionDismissed(int position, const GURL& url) { +void FeedLoggingMetrics::OnSuggestionDismissed(int position, + const GURL& url, + bool committed) { history_url_check_callback_.Run( - url, base::BindOnce(&FeedLoggingMetrics::CheckURLVisitedDone, - weak_ptr_factory_.GetWeakPtr(), position)); + url, base::BindOnce(&CheckURLVisitedDone, position, committed)); base::RecordAction(base::UserMetricsAction("Suggestions.Content.Dismissed")); } @@ -221,25 +295,116 @@ void FeedLoggingMetrics::OnMoreButtonClicked(int position) { kMaxSuggestionsForArticle + 1); } -void FeedLoggingMetrics::OnSpinnerShown(base::TimeDelta shown_time) { - base::UmaHistogramTimes( - "ContentSuggestions.Feed.FetchPendingSpinner.VisibleDuration", - shown_time); +void FeedLoggingMetrics::OnNotInterestedInSource(int position, bool committed) { + RecordUndoableActionUMA( + "ContentSuggestions.Feed.InterestHeader.NotInterestedInSource", position, + committed); } -void FeedLoggingMetrics::ReportScrolledAfterOpen() { - base::RecordAction(base::UserMetricsAction("Suggestions.ScrolledAfterOpen")); +void FeedLoggingMetrics::OnNotInterestedInTopic(int position, bool committed) { + RecordUndoableActionUMA( + "ContentSuggestions.Feed.InterestHeader.NotInterestedInTopic", position, + committed); } -void FeedLoggingMetrics::CheckURLVisitedDone(int position, bool visited) { - if (visited) { - UMA_HISTOGRAM_EXACT_LINEAR("NewTabPage.ContentSuggestions.DismissedVisited", - position, kMaxSuggestionsTotal); +void FeedLoggingMetrics::OnSpinnerStarted(int spinner_type) { + // TODO(https://crbug.com/935602): Handle new values when adding new values on + // java side. + SpinnerType type = static_cast<SpinnerType>(spinner_type); + UMA_HISTOGRAM_ENUMERATION("ContentSuggestions.Feed.FetchPendingSpinner.Shown", + type); +} + +void FeedLoggingMetrics::OnSpinnerFinished(base::TimeDelta shown_time, + int spinner_type) { + RecordSpinnerTimeUMA( + "ContentSuggestions.Feed.FetchPendingSpinner.VisibleDuration", shown_time, + spinner_type); +} + +void FeedLoggingMetrics::OnSpinnerDestroyedWithoutCompleting( + base::TimeDelta shown_time, + int spinner_type) { + RecordSpinnerTimeUMA( + "ContentSuggestions.Feed.FetchPendingSpinner." + "VisibleDurationWithoutCompleting", + shown_time, spinner_type); +} + +void FeedLoggingMetrics::OnPietFrameRenderingEvent( + std::vector<int> piet_error_codes) { + for (auto error_code : piet_error_codes) { + base::UmaHistogramSparse( + "ContentSuggestions.Feed.Piet.FrameRenderingErrorCode", error_code); + } +} + +void FeedLoggingMetrics::OnInternalError(int internal_error) { + // TODO(https://crbug.com/935602): The max value here is fragile, figure out + // some way to test the @IntDef size. + UMA_HISTOGRAM_ENUMERATION("ContentSuggestions.Feed.InternalError", + internal_error, 10); +} + +void FeedLoggingMetrics::OnTokenCompleted(bool was_synthetic, + int content_count, + int token_count) { + if (was_synthetic) { + UMA_HISTOGRAM_EXACT_LINEAR( + "ContentSuggestions.Feed.TokenCompleted.ContentCount2.Synthetic", + content_count, kMaxContentCount); + UMA_HISTOGRAM_EXACT_LINEAR( + "ContentSuggestions.Feed.TokenCompleted.TokenCount.Synthetic", + token_count, kMaxTokenCount); + } else { + UMA_HISTOGRAM_EXACT_LINEAR( + "ContentSuggestions.Feed.TokenCompleted.ContentCount2.NotSynthetic", + content_count, kMaxContentCount); + UMA_HISTOGRAM_EXACT_LINEAR( + "ContentSuggestions.Feed.TokenCompleted.TokenCount.NotSynthetic", + token_count, kMaxTokenCount); + } +} + +void FeedLoggingMetrics::OnTokenFailedToComplete(bool was_synthetic, + int failure_count) { + if (was_synthetic) { + UMA_HISTOGRAM_EXACT_LINEAR( + "ContentSuggestions.Feed.TokenFailedToCompleted.Synthetic", + failure_count, kMaxFailureCount); } else { UMA_HISTOGRAM_EXACT_LINEAR( - "NewTabPage.ContentSuggestions.DismissedUnvisited", position, - kMaxSuggestionsTotal); + "ContentSuggestions.Feed.TokenFailedToCompleted.NotSynthetic", + failure_count, kMaxFailureCount); } } +void FeedLoggingMetrics::OnServerRequest(int request_reason) { + // TODO(https://crbug.com/935602): The max value here is fragile, figure out + // some way to test the @IntDef size. + UMA_HISTOGRAM_ENUMERATION("ContentSuggestions.Feed.ServerRequest.Reason", + request_reason, 8); +} + +void FeedLoggingMetrics::OnZeroStateShown(int zero_state_show_reason) { + // TODO(https://crbug.com/935602): The max value here is fragile, figure out + // some way to test the @IntDef size. + UMA_HISTOGRAM_ENUMERATION("ContentSuggestions.Feed.ZeroStateShown.Reason", + zero_state_show_reason, 3); +} + +void FeedLoggingMetrics::OnZeroStateRefreshCompleted(int new_content_count, + int new_token_count) { + UMA_HISTOGRAM_EXACT_LINEAR( + "ContentSuggestions.Feed.ZeroStateRefreshCompleted.ContentCount", + new_content_count, kMaxContentCount); + UMA_HISTOGRAM_EXACT_LINEAR( + "ContentSuggestions.Feed.ZeroStateRefreshCompleted.TokenCount", + new_token_count, kMaxTokenCount); +} + +void FeedLoggingMetrics::ReportScrolledAfterOpen() { + base::RecordAction(base::UserMetricsAction("Suggestions.ScrolledAfterOpen")); +} + } // namespace feed |