blob: 334df713b17e2df9ad7c2fe0879705086c9d3e22 [file] [log] [blame]
// 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.
#ifndef CHROME_BROWSER_PREDICTORS_LOADING_DATA_COLLECTOR_H_
#define CHROME_BROWSER_PREDICTORS_LOADING_DATA_COLLECTOR_H_
#include <map>
#include <memory>
#include <string>
#include "base/memory/weak_ptr.h"
#include "chrome/browser/predictors/loading_predictor_config.h"
#include "chrome/browser/predictors/resource_prefetch_common.h"
#include "content/public/common/resource_load_info.mojom.h"
#include "content/public/common/resource_type.h"
#include "url/gurl.h"
namespace predictors {
class LoadingStatsCollector;
class ResourcePrefetchPredictor;
// Data collected for origin-based prediction, for a single origin during a
// page load (see PageRequestSummary).
struct OriginRequestSummary {
OriginRequestSummary();
OriginRequestSummary(const OriginRequestSummary& other);
~OriginRequestSummary();
GURL origin;
bool always_access_network = false;
bool accessed_network = false;
int first_occurrence = 0;
};
// Stores the data learned from a single navigation.
struct PageRequestSummary {
explicit PageRequestSummary(const GURL& main_frame_url);
PageRequestSummary(const PageRequestSummary& other);
~PageRequestSummary();
void UpdateOrAddToOrigins(
const content::mojom::ResourceLoadInfo& resource_load_info);
GURL main_frame_url;
GURL initial_url;
base::TimeTicks first_contentful_paint;
// Map of origin -> OriginRequestSummary. Only one instance of each origin
// is kept per navigation, but the summary is updated several times.
std::map<GURL, OriginRequestSummary> origins;
private:
void UpdateOrAddToOrigins(
const GURL& url,
const content::mojom::CommonNetworkInfoPtr& network_info);
};
// Records navigation events as reported by various observers to the database
// and stats collection classes. All the non-static methods of this class need
// to be called on the UI thread.
class LoadingDataCollector {
public:
explicit LoadingDataCollector(
predictors::ResourcePrefetchPredictor* predictor,
predictors::LoadingStatsCollector* stats_collector,
const LoadingPredictorConfig& config);
virtual ~LoadingDataCollector();
// |LoadingPredictorTabHelper| calls the below functions to inform the
// collector of navigation and resource load events.
virtual void RecordStartNavigation(const NavigationID& navigation_id);
virtual void RecordFinishNavigation(const NavigationID& old_navigation_id,
const NavigationID& new_navigation_id,
bool is_error_page);
virtual void RecordResourceLoadComplete(
const NavigationID& navigation_id,
const content::mojom::ResourceLoadInfo& resource_load_info);
// Called when the main frame of a page completes loading. We treat this point
// as the "completion" of the navigation. The resources requested by the page
// up to this point are the only ones considered.
virtual void RecordMainFrameLoadComplete(const NavigationID& navigation_id);
// Called after the main frame's first contentful paint.
virtual void RecordFirstContentfulPaint(
const NavigationID& navigation_id,
const base::TimeTicks& first_contentful_paint);
private:
using NavigationMap =
std::map<NavigationID, std::unique_ptr<PageRequestSummary>>;
friend class LoadingDataCollectorTest;
FRIEND_TEST_ALL_PREFIXES(LoadingDataCollectorTest, HandledResourceTypes);
FRIEND_TEST_ALL_PREFIXES(LoadingDataCollectorTest, ShouldRecordMainFrameLoad);
FRIEND_TEST_ALL_PREFIXES(LoadingDataCollectorTest,
ShouldRecordSubresourceLoad);
FRIEND_TEST_ALL_PREFIXES(LoadingDataCollectorTest, SimpleNavigation);
FRIEND_TEST_ALL_PREFIXES(LoadingDataCollectorTest, SimpleRedirect);
FRIEND_TEST_ALL_PREFIXES(LoadingDataCollectorTest,
RecordStartNavigationMissing);
FRIEND_TEST_ALL_PREFIXES(LoadingDataCollectorTest, RecordFailedNavigation);
FRIEND_TEST_ALL_PREFIXES(LoadingDataCollectorTest, ManyNavigations);
FRIEND_TEST_ALL_PREFIXES(LoadingDataCollectorTest,
RecordResourceLoadComplete);
static void SetAllowPortInUrlsForTesting(bool state);
static bool ShouldRecordResourceLoad(
const content::mojom::ResourceLoadInfo& resource_load_info);
// Returns true if the subresource has a supported type.
static bool IsHandledResourceType(content::ResourceType resource_type,
const std::string& mime_type);
// Cleanup inflight_navigations_ and call a cleanup for stats_collector_.
void CleanupAbandonedNavigations(const NavigationID& navigation_id);
ResourcePrefetchPredictor* const predictor_;
LoadingStatsCollector* const stats_collector_;
const LoadingPredictorConfig config_;
NavigationMap inflight_navigations_;
};
} // namespace predictors
#endif // CHROME_BROWSER_PREDICTORS_LOADING_DATA_COLLECTOR_H_