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 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375
|
// 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 COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_GRAPH_PAGE_NODE_H_
#define COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_GRAPH_PAGE_NODE_H_
#include <iosfwd>
#include <optional>
#include <string>
#include "base/containers/flat_set.h"
#include "base/observer_list_types.h"
#include "base/time/time.h"
#include "components/performance_manager/public/graph/node.h"
#include "components/performance_manager/public/graph/node_set_view.h"
#include "components/performance_manager/public/mojom/lifecycle.mojom.h"
#include "services/metrics/public/cpp/ukm_source_id.h"
#include "third_party/blink/public/common/permissions/permission_utils.h"
class GURL;
namespace content {
class WebContents;
}
namespace resource_attribution {
class PageContext;
}
namespace performance_manager {
class FrameNode;
class PageNodeObserver;
enum class PageType {
// A browser tab.
kTab,
// An extension background page.
kExtension,
// Anything else.
kUnknown,
};
// A PageNode represents the root of a FrameTree, or equivalently a WebContents.
// These may correspond to normal tabs, WebViews, Chrome Apps or Extensions.
class PageNode : public TypedNode<PageNode> {
public:
using NodeSet = base::flat_set<const Node*>;
template <class NodeViewPtr>
using NodeSetView = NodeSetView<NodeSet, NodeViewPtr>;
using LifecycleState = mojom::LifecycleState;
// Loading state of a page.
enum class LoadingState {
// No top-level document has started loading yet.
kLoadingNotStarted,
// A different top-level document is loading. The load started less than 5
// seconds ago or the initial response was received.
kLoading,
// A different top-level document is loading. The load started more than 5
// seconds ago and no response was received yet. Note: The state will
// transition back to |kLoading| if a response is received.
kLoadingTimedOut,
// A different top-level document finished loading, but the page did not
// reach CPU and network quiescence since then. Note: A page is considered
// to have reached CPU and network quiescence after 1 minute, even if the
// CPU and network are still busy - see page_load_tracker_decorator.h.
kLoadedBusy,
// The page reached CPU and network quiescence after loading the current
// top-level document, or the load failed.
kLoadedIdle,
};
// Returns a string for an enumeration value.
static const char* ToString(PageType type);
static const char* ToString(PageNode::LoadingState loading_state);
static constexpr NodeTypeEnum Type() { return NodeTypeEnum::kPage; }
PageNode();
PageNode(const PageNode&) = delete;
PageNode& operator=(const PageNode&) = delete;
~PageNode() override;
// Returns the unique ID of the browser context that this page belongs to.
virtual const std::string& GetBrowserContextID() const = 0;
// Returns the opener frame node, if there is one. This may change over the
// lifetime of this page. See "OnOpenerFrameNodeChanged".
virtual const FrameNode* GetOpenerFrameNode() const = 0;
// Returns the embedder frame node, if there is one. This may change over the
// lifetime of this page. See "OnEmbedderFrameNodeChanged".
virtual const FrameNode* GetEmbedderFrameNode() const = 0;
// Gets the unique token identifying this node for resource attribution. This
// token will not be reused after the node is destroyed.
virtual resource_attribution::PageContext GetResourceContext() const = 0;
// Returns the type of the page.
virtual PageType GetType() const = 0;
// Returns true if this page has the focus.
virtual bool IsFocused() const = 0;
// Returns true if this page is currently visible, false otherwise.
// See PageNodeObserver::OnIsVisibleChanged.
virtual bool IsVisible() const = 0;
// Returns the time of the last visibility change. It is always well defined
// as the visibility property is set at node creation.
virtual base::TimeTicks GetLastVisibilityChangeTime() const = 0;
// Returns true if this page is currently audible, false otherwise.
// See PageNodeObserver::OnIsAudibleChanged.
virtual bool IsAudible() const = 0;
// Returns the time since the last audible change. Unlike
// GetLastVisibilityChangeTime(), this returns nullopt for a node which has
// never been audible. If a node is audible when created, it is considered to
// change from inaudible to audible at that point.
virtual std::optional<base::TimeDelta> GetTimeSinceLastAudibleChange()
const = 0;
// Returns true if this page is displaying content in a picture-in-picture
// window, false otherwise.
virtual bool HasPictureInPicture() const = 0;
// Returns true if this page is opted-out from freezing via origin trial, i.e.
// if any of its current frames sets the origin trial.
virtual bool HasFreezingOriginTrialOptOut() const = 0;
// Returns true if this page is off the record, false otherwise.
// A tab is off the record when it is open in incognito or guest mode.
virtual bool IsOffTheRecord() const = 0;
// Returns the page's loading state.
virtual LoadingState GetLoadingState() const = 0;
// Returns the UKM source ID associated with the URL of the main frame of
// this page.
// See PageNodeObserver::OnUkmSourceIdChanged.
virtual ukm::SourceId GetUkmSourceID() const = 0;
// Returns the lifecycle state of this page. This is aggregated from the
// lifecycle state of each frame in the frame tree. See
// PageNodeObserver::OnPageLifecycleStateChanged.
virtual LifecycleState GetLifecycleState() const = 0;
// Returns true if at least one of the frame in this page is currently
// holding a WebLock.
virtual bool IsHoldingWebLock() const = 0;
// Returns true if at least one of the frame in this page is currently
// holding an IndexedDB lock that is blocking another client.
virtual bool IsHoldingBlockingIndexedDBLock() const = 0;
// Returns whether at least one frame on this page currently uses WebRTC.
virtual bool UsesWebRTC() const = 0;
// Returns the navigation ID associated with the last committed navigation
// event for the main frame of this page.
// See PageNodeObserver::OnMainFrameNavigationCommitted.
virtual int64_t GetNavigationID() const = 0;
// Returns the MIME type for the last committed main frame navigation.
virtual const std::string& GetContentsMimeType() const = 0;
// Returns the notification permission status for the last committed main
// frame navigation (nullopt if it wasn't retrieved).
virtual std::optional<blink::mojom::PermissionStatus>
GetNotificationPermissionStatus() const = 0;
// Returns "zero" if no navigation has happened, otherwise returns the time
// since the last navigation commit.
virtual base::TimeDelta GetTimeSinceLastNavigation() const = 0;
// Returns the current main frame node (if there is one), otherwise returns
// any of the potentially multiple main frames that currently exist. If there
// are no main frames at the moment, returns nullptr.
virtual const FrameNode* GetMainFrameNode() const = 0;
// Returns all of the main frame nodes, both current and otherwise. If there
// are no main frames at the moment, returns the empty set.
virtual NodeSetView<const FrameNode*> GetMainFrameNodes() const = 0;
// Returns the URL the main frame last committed a navigation to, or the
// initial URL of the page before navigation. The latter case is distinguished
// by a zero navigation ID.
// See PageNodeObserver::OnMainFrameNavigationCommitted.
virtual const GURL& GetMainFrameUrl() const = 0;
// Returns the private memory footprint size of the main frame and its
// children. This differs from EstimatePrivateFootprintSize which includes
// all the frames under the page node.
virtual uint64_t EstimateMainFramePrivateFootprintSize() const = 0;
// Indicates if at least one of the frames in the page has received some form
// interactions.
virtual bool HadFormInteraction() const = 0;
// Indicates if at least one of the frames in the page has received
// user-initiated edits. This is a superset of `HadFormInteraction()` that
// also includes changes to `contenteditable` elements.
virtual bool HadUserEdits() const = 0;
// Returns the web contents associated with this page node. It is valid to
// call this function on any thread but the weak pointer must only be
// dereferenced on the UI thread.
virtual base::WeakPtr<content::WebContents> GetWebContents() const = 0;
virtual uint64_t EstimateResidentSetSize() const = 0;
virtual uint64_t EstimatePrivateFootprintSize() const = 0;
// Returns a weak pointer to this page node.
virtual base::WeakPtr<PageNode> GetWeakPtr() = 0;
virtual base::WeakPtr<const PageNode> GetWeakPtr() const = 0;
};
// Observer interface for page nodes.
class PageNodeObserver : public base::CheckedObserver {
public:
PageNodeObserver();
PageNodeObserver(const PageNodeObserver&) = delete;
PageNodeObserver& operator=(const PageNodeObserver&) = delete;
~PageNodeObserver() override;
// Node lifetime notifications.
// Called before a `page_node` is added to the graph. OnPageNodeAdded() is
// better for most purposes, but this can be useful if an observer needs to
// check the state of the graph without including `page_node`, or to set
// initial properties on the node that should be visible to other observers in
// OnPageNodeAdded().
//
// Observers may make property changes during the scope of this call, as long
// as they don't cause notifications to be sent and don't modify pointers
// to/from other nodes, since the node is still isolated from the graph. To
// change a property that causes notifications, post a task (which will run
// after OnPageNodeAdded().
//
// Note that observers are notified in an arbitrary order, so property changes
// made here may or may not be visible to other observers in
// OnBeforePageNodeAdded().
virtual void OnBeforePageNodeAdded(const PageNode* page_node) {}
// Called after a `page_node` is added to the graph. Observers may *not* make
// property changes during the scope of this call. To change a property, post
// a task which will run after all observers.
virtual void OnPageNodeAdded(const PageNode* page_node) {}
// Called before a `page_node` is removed from the graph. Observers may *not*
// make property changes during the scope of this call. The node will be
// deleted before any task posted from this scope runs.
virtual void OnBeforePageNodeRemoved(const PageNode* page_node) {}
// Called after a `page_node` is removed from the graph.
// OnBeforePageNodeRemoved() is better for most purposes, but this can be
// useful if an observer needs to check the state of the graph without
// including `page_node`.
//
// Observers may *not* make property changes during the scope of this call.
// The node will be deleted before any task posted from this scope runs.
virtual void OnPageNodeRemoved(const PageNode* page_node) {}
// Notifications of property changes.
// Invoked when this page has been assigned an opener, had the opener
// change, or had the opener removed. This happens when a page is opened
// via window.open, or when that relationship is subsequently severed or
// reparented.
virtual void OnOpenerFrameNodeChanged(const PageNode* page_node,
const FrameNode* previous_opener) {}
// Invoked when this page has been assigned an embedder, had the embedder
// change, or had the embedder removed. This can happen if a page is opened
// via webviews, guestviews etc, or when that relationship is subsequently
// severed or reparented.
virtual void OnEmbedderFrameNodeChanged(const PageNode* page_node,
const FrameNode* previous_embedder) {}
// Invoked when the GetType property changes.
virtual void OnTypeChanged(const PageNode* page_node,
PageType previous_type) {}
// Invoked when the IsFocused property changes.
virtual void OnIsFocusedChanged(const PageNode* page_node) {}
// Invoked when the IsVisible property changes.
//
// GetLastVisibilityChangeTime() will return the time of the previous
// IsVisible change. After all observers have fired it will return the time of
// this property change.
virtual void OnIsVisibleChanged(const PageNode* page_node) {}
// Invoked when the IsAudible property changes.
//
// GetTimeSinceLastAudibleChange() will return the time since the previous
// IsAudible change. After all observers have fired it will return the time of
// this property change.
virtual void OnIsAudibleChanged(const PageNode* page_node) {}
// Invoked when the HasPictureInPicture property changes.
virtual void OnHasPictureInPictureChanged(const PageNode* page_node) {}
// Invoked when the HasFreezingOriginTrialOptOut() property changes.
virtual void OnPageHasFreezingOriginTrialOptOutChanged(
const PageNode* page_node) {}
// Invoked when the GetLoadingState property changes.
virtual void OnLoadingStateChanged(const PageNode* page_node,
PageNode::LoadingState previous_state) {}
// Invoked when the UkmSourceId property changes.
virtual void OnUkmSourceIdChanged(const PageNode* page_node) {}
// Invoked when the PageLifecycleState property changes.
virtual void OnPageLifecycleStateChanged(const PageNode* page_node) {}
// Invoked when the IsHoldingWebLock property changes.
virtual void OnPageIsHoldingWebLockChanged(const PageNode* page_node) {}
// Invoked when the IsHoldingBlockingIndexedDBLock property changes.
virtual void OnPageIsHoldingBlockingIndexedDBLockChanged(
const PageNode* page_node) {}
// Invoked when the UsesWebRTC property changes.
virtual void OnPageUsesWebRTCChanged(const PageNode* page_node) {}
// Invoked when the GetNotificationPermissionStatus property changes.
virtual void OnPageNotificationPermissionStatusChange(
const PageNode* page_node,
std::optional<blink::mojom::PermissionStatus> previous_status) {}
// Invoked when the MainFrameUrl property changes.
virtual void OnMainFrameUrlChanged(const PageNode* page_node) {}
// This is fired when a non-same document navigation commits in the main
// frame. It indicates that the the |NavigationId| property and possibly the
// |MainFrameUrl| properties have changed.
virtual void OnMainFrameDocumentChanged(const PageNode* page_node) {}
// Invoked when the HadFormInteraction property changes.
virtual void OnHadFormInteractionChanged(const PageNode* page_node) {}
// Invoked when the HadUserEdits property changes.
virtual void OnHadUserEditsChanged(const PageNode* page_node) {}
// Events with no property changes.
// Fired when the tab title associated with a page changes. This property is
// not directly reflected on the node.
virtual void OnTitleUpdated(const PageNode* page_node) {}
// Fired when the favicon associated with a page is updated. This property is
// not directly reflected on the node.
virtual void OnFaviconUpdated(const PageNode* page_node) {}
// Fired after `new_page_node` is created but before `page_node` is deleted
// from being discarded. See the equivalent function on `WebContentsObserver`
// for more detail.
virtual void OnAboutToBeDiscarded(const PageNode* page_node,
const PageNode* new_page_node) {}
};
} // namespace performance_manager
#endif // COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_GRAPH_PAGE_NODE_H_
|