blob: 241805b1cb729d18aa7a35b6dcc96910babb4373 [file] [log] [blame]
// Copyright 2020 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_V2_METRICS_REPORTER_H_
#define COMPONENTS_FEED_CORE_V2_METRICS_REPORTER_H_
#include <climits>
#include <map>
#include "base/memory/weak_ptr.h"
#include "base/optional.h"
#include "base/time/time.h"
#include "components/feed/core/v2/enums.h"
#include "components/feed/core/v2/feed_stream.h"
namespace feed {
// Reports UMA metrics for feed.
// Note this is inherited only for testing.
class MetricsReporter {
public:
// For 'index_in_stream' parameters, when the card index is unknown.
// This is most likely to happen when the action originates from the bottom
// sheet.
static const int kUnknownCardIndex = INT_MAX;
explicit MetricsReporter(PrefService* profile_prefs);
virtual ~MetricsReporter();
MetricsReporter(const MetricsReporter&) = delete;
MetricsReporter& operator=(const MetricsReporter&) = delete;
// User interactions. See |FeedStreamApi| for definitions.
virtual void ContentSliceViewed(SurfaceId surface_id, int index_in_stream);
void FeedViewed(SurfaceId surface_id);
void OpenAction(int index_in_stream);
void OpenVisitComplete(base::TimeDelta visit_time);
void OpenInNewTabAction(int index_in_stream);
void OpenInNewIncognitoTabAction();
void SendFeedbackAction();
void LearnMoreAction();
void DownloadAction();
void NavigationStarted();
void PageLoaded();
void RemoveAction();
void NotInterestedInAction();
void ManageInterestsAction();
void ContextMenuOpened();
void EphemeralStreamChange();
void EphemeralStreamChangeRejected();
void TurnOnAction();
void TurnOffAction();
// Indicates the user scrolled the feed by |distance_dp| and then stopped
// scrolling.
void StreamScrolled(int distance_dp);
void StreamScrollStart();
// Called when the Feed surface is opened and closed.
void SurfaceOpened(SurfaceId surface_id);
void SurfaceClosed(SurfaceId surface_id);
// Network metrics.
static void NetworkRequestComplete(NetworkRequestType type,
int http_status_code);
// Stream events.
virtual void OnLoadStream(LoadStreamStatus load_from_store_status,
LoadStreamStatus final_status,
bool loaded_new_content_from_network,
base::TimeDelta stored_content_age,
std::unique_ptr<LoadLatencyTimes> load_latencies);
virtual void OnBackgroundRefresh(LoadStreamStatus final_status);
virtual void OnLoadMoreBegin(SurfaceId surface_id);
virtual void OnLoadMore(LoadStreamStatus final_status);
virtual void OnClearAll(base::TimeDelta time_since_last_clear);
// Called each time the surface receives new content.
void SurfaceReceivedContent(SurfaceId surface_id);
// Called when Chrome is entering the background.
void OnEnterBackground();
static void OnImageFetched(int net_error_or_http_status);
// Actions upload.
static void OnUploadActionsBatch(UploadActionsBatchStatus status);
virtual void OnUploadActions(UploadActionsStatus status);
static void ActivityLoggingEnabled(bool response_has_logging_enabled);
static void NoticeCardFulfilled(bool response_has_notice_card);
static void NoticeCardFulfilledObsolete(bool response_has_notice_card);
private:
base::WeakPtr<MetricsReporter> GetWeakPtr() {
return weak_ptr_factory_.GetWeakPtr();
}
void ReportPersistentDataIfDayIsDone();
void CardOpenBegin();
void CardOpenTimeout(base::TimeTicks start_ticks);
void ReportCardOpenEndIfNeeded(bool success);
void RecordEngagement(int scroll_distance_dp, bool interacted);
void TrackTimeSpentInFeed(bool interacted_or_scrolled);
void RecordInteraction();
void ReportOpenFeedIfNeeded(SurfaceId surface_id, bool success);
void ReportGetMoreIfNeeded(SurfaceId surface_id, bool success);
void FinalizeMetrics();
void FinalizeVisit();
PrefService* profile_prefs_;
// Persistent data stored in prefs. Data is read in the constructor, and then
// written back to prefs on backgrounding.
PersistentMetricsData persistent_data_;
base::TimeTicks visit_start_time_;
bool engaged_simple_reported_ = false;
bool engaged_reported_ = false;
bool scrolled_reported_ = false;
// The time a surface was opened, for surfaces still waiting for content.
std::map<SurfaceId, base::TimeTicks> surfaces_waiting_for_content_;
// The time a surface requested more content, for surfaces still waiting for
// more content.
std::map<SurfaceId, base::TimeTicks> surfaces_waiting_for_more_content_;
// Tracking ContentSuggestions.Feed.UserJourney.OpenCard.*:
// We assume at most one card is opened at a time. The time the card was
// tapped is stored here. Upon timeout, another open attempt, or
// |ChromeStopping()|, the open is considered failed. Otherwise, if the
// loading the page succeeds, the open is considered successful.
base::Optional<base::TimeTicks> pending_open_;
// For tracking time spent in the Feed.
base::Optional<base::TimeTicks> time_in_feed_start_;
// For TimeSpentOnFeed.
base::TimeDelta tracked_visit_time_in_feed_;
// Non-null only directly after a stream load.
std::unique_ptr<LoadLatencyTimes> load_latencies_;
bool load_latencies_recorded_ = false;
base::WeakPtrFactory<MetricsReporter> weak_ptr_factory_{this};
};
} // namespace feed
#endif // COMPONENTS_FEED_CORE_V2_METRICS_REPORTER_H_