1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
|
// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_BROWSER_RENDERER_HOST_NAVIGATION_THROTTLE_RUNNER_H_
#define CONTENT_BROWSER_RENDERER_HOST_NAVIGATION_THROTTLE_RUNNER_H_
#include <stddef.h>
#include <optional>
#include <vector>
#include "base/memory/raw_ptr.h"
#include "base/memory/safety_checks.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "content/common/content_export.h"
#include "content/public/browser/navigation_throttle.h"
#include "content/public/browser/navigation_throttle_registry.h"
namespace content {
class NavigationHandle;
// This class owns the set of NavigationThrottles added to a NavigationHandle.
// It is responsible for calling the various sets of events on its
// NavigationThrottle, and notifying its delegate of the results of said events.
// TODO(https://crbug.com/412524375): Currently this class implements
// NavigationThrottleRegistry, but this will be factored out to a separate
// NavigationThrottleRegistryImpl class, and will hold common logic for the
// legacy NavigationThrottleRunner, and the new NavigationThrottleRunner2.
class CONTENT_EXPORT NavigationThrottleRunner
: public NavigationThrottleRegistry {
// Do not remove this macro!
// The macro is maintained by the memory safety team.
ADVANCED_MEMORY_SAFETY_CHECKS();
public:
// The different event types that can be processed by NavigationThrottles.
// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
// This type is also used in the UKM as set in the RecordDeferTimeUKM().
//
// LINT.IfChange(Event)
enum class Event {
kNoEvent = 0,
kWillStartRequest = 1,
kWillRedirectRequest = 2,
kWillFailRequest = 3,
kWillProcessResponse = 4,
kWillCommitWithoutUrlLoader = 5,
kMaxValue = kWillCommitWithoutUrlLoader,
};
// LINT.ThenChange(//tools/metrics/histograms/metadata/navigation/enums.xml:NavigationThrottleEvent)
class Delegate {
public:
// Called when the NavigationThrottleRunner is done processing the
// navigation event of type |event|. |result| is the final
// NavigationThrottle::ThrottleCheckResult for this event.
virtual void OnNavigationEventProcessed(
Event event,
NavigationThrottle::ThrottleCheckResult result) = 0;
};
NavigationThrottleRunner(Delegate* delegate,
int64_t navigation_id,
bool is_primary_main_frame);
NavigationThrottleRunner(const NavigationThrottleRunner&) = delete;
NavigationThrottleRunner& operator=(const NavigationThrottleRunner&) = delete;
~NavigationThrottleRunner() override;
// Implements NavigationThrottleRegistry:
NavigationHandle& GetNavigationHandle() override;
void AddThrottle(
std::unique_ptr<NavigationThrottle> navigation_throttle) override;
void MaybeAddThrottle(
std::unique_ptr<NavigationThrottle> navigation_throttle) override;
// Will call the appropriate NavigationThrottle function based on |event| on
// all NavigationThrottles owned by this NavigationThrottleRunner.
void ProcessNavigationEvent(Event event);
// Resumes calling the appropriate NavigationThrottle functions for |event_|
// on all NavigationThrottles that have not yet been notified.
// |resuming_throttle| is the NavigationThrottle that asks for navigation
// event processing to be resumed; it should be the one currently deferring
// the navigation.
void ResumeProcessingNavigationEvent(NavigationThrottle* resuming_throttle);
// Simulates the navigation resuming. Most callers should just let the
// deferring NavigationThrottle do the resuming.
void CallResumeForTesting();
// Registers the appropriate NavigationThrottles are added for a "standard"
// navigation (i.e., one with a URLLoader that goes through the
// WillSendRequest/WillProcessResponse callback sequence).
void RegisterNavigationThrottles();
// Registers the appropriate NavigationThrottles for a navigation that can
// immediately commit because no URLLoader is required (about:blank,
// about:srcdoc, and most same-document navigations).
void RegisterNavigationThrottlesForCommitWithoutUrlLoader();
// Returns the throttle that is currently deferring the navigation (i.e. the
// throttle at index |next_index_ -1|). If the handle is not deferred, returns
// nullptr;
NavigationThrottle* GetDeferringThrottle() const;
void set_first_deferral_callback_for_testing(base::OnceClosure callback) {
first_deferral_callback_for_testing_ = std::move(callback);
}
private:
void ProcessInternal();
void InformDelegate(const NavigationThrottle::ThrottleCheckResult& result);
// Records UKM about the deferring throttle when the navigation is resumed.
void RecordDeferTimeUKM();
const raw_ptr<Delegate> delegate_;
// A list of Throttles registered for this navigation.
std::vector<std::unique_ptr<NavigationThrottle>> throttles_;
// The index of the next throttle to check.
size_t next_index_;
// The unique id of the navigation which this throttle runner is associated
// with.
const int64_t navigation_id_;
// The time a throttle started deferring the navigation.
base::Time defer_start_time_;
// The total duration time that throttles deferred the navigation.
base::TimeDelta total_defer_duration_time_;
base::TimeDelta total_defer_duration_time_for_request_;
// The time this runner started ProcessInternal() for the current_event_.
// Should be reset when the processing is done.
std::optional<base::Time> event_process_start_time_;
// The accumulated time duration this runner took to execute throttles for the
// current_event_.
base::TimeDelta event_process_execution_time_;
// The total count to know how many times a throttle defer the navigation.
size_t defer_count_ = 0;
size_t defer_count_for_request_ = 0;
// This test-only callback will be run the first time a NavigationThrottle
// defers this navigation.
base::OnceClosure first_deferral_callback_for_testing_;
// The event currently being processed.
Event current_event_ = Event::kNoEvent;
// Whether the navigation is in the primary main frame.
bool is_primary_main_frame_ = false;
base::WeakPtrFactory<NavigationThrottleRunner> weak_factory_{this};
};
} // namespace content
#endif // CONTENT_BROWSER_RENDERER_HOST_NAVIGATION_THROTTLE_RUNNER_H_
|