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
|
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_RENDERER_ACTOR_PAGE_STABILITY_MONITOR_H_
#define CHROME_RENDERER_ACTOR_PAGE_STABILITY_MONITOR_H_
#include "base/cancelable_callback.h"
#include "base/functional/callback_forward.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "chrome/renderer/actor/journal.h"
#include "content/public/renderer/render_frame_observer.h"
namespace content {
class RenderFrame;
} // namespace content
namespace actor {
class ToolBase;
// Helper class for monitoring page stability after tool usage. Its lifetime
// must not outlive the RenderFrame it is observing. This object is single-use,
// i.e. WaitForStable can only be called once.
class PageStabilityMonitor : public content::RenderFrameObserver {
public:
// Constructs the monitor and takes a baseline observation of the document in
// the given RenderFrame.
explicit PageStabilityMonitor(content::RenderFrame& frame);
~PageStabilityMonitor() override;
// Invokes the given callback when the page is deemed stable enough for an
// observation to take place or when the document is no longer active.
void WaitForStable(const ToolBase& tool,
int32_t task_id,
Journal& journal,
base::OnceClosure callback);
// RenderFrameObserver
void DidCommitProvisionalLoad(ui::PageTransition transition) override;
void DidFailProvisionalLoad() override;
void OnDestruct() override;
private:
enum class State {
kInitial,
// Entry point into the state machine. Decides which state to start in.
kStartMonitoring,
// A navigation was started, wait for it to commit or cancel.
kWaitForNavigation,
// Wait until all network requests complete.
kWaitForNetworkIdle,
// Wait until the main thread is settled.
kWaitForMainThreadIdle,
// Ensure the minimum delay time has been met.
kEnsureMinimumDelay,
// Wait until a new frame has been submitted to and presented by the display
// compositor.
kWaitForVisualStateRequest,
// Timeout states - these just log and and move to invoke callback state.
kTimeoutGlobal,
kTimeoutMainThread,
// Invoke the callback passed to WaitForStable and cleanup.
kInvokeCallback,
kDone
} state_ = State::kInitial;
friend std::ostream& operator<<(std::ostream& o,
const PageStabilityMonitor::State& state);
// Synchronously moves to the given state.
void MoveToState(State new_state);
// Helper that provides a closure that invokes MoveToState with the given
// State on the default task queue for the sequence that created this object.
base::OnceClosure PostMoveToStateClosure(
State new_state,
base::TimeDelta delay = base::TimeDelta());
void SetTimeout(State timeout_type, base::TimeDelta delay);
void DCheckStateTransition(State old_state, State new_state);
// The number of active network requests at the time this object was
// initialized. Used to compare to the number of requests after monitoring
// begins to determine if new network requests were started in that interval.
int starting_request_count_;
// Track the callback given to the RequestNetworkIdle method so that it can be
// canceled, the API supports only one request at a time.
base::CancelableOnceClosure network_idle_callback_;
base::OnceClosure is_stable_callback_;
std::unique_ptr<Journal::PendingAsyncEntry> journal_entry_;
// This value is set to prevent the monitor from returning sooner than this
// time.
base::TimeTicks minimum_end_time_;
base::WeakPtrFactory<PageStabilityMonitor> weak_ptr_factory_{this};
};
} // namespace actor
#endif // CHROME_RENDERER_ACTOR_PAGE_STABILITY_MONITOR_H_
|