diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-10-12 14:27:29 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-10-13 09:35:20 +0000 |
commit | c30a6232df03e1efbd9f3b226777b07e087a1122 (patch) | |
tree | e992f45784689f373bcc38d1b79a239ebe17ee23 /chromium/chrome/browser/ui/webui/discards | |
parent | 7b5b123ac58f58ffde0f4f6e488bcd09aa4decd3 (diff) | |
download | qtwebengine-chromium-85-based.tar.gz |
BASELINE: Update Chromium to 85.0.4183.14085-based
Change-Id: Iaa42f4680837c57725b1344f108c0196741f6057
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/chrome/browser/ui/webui/discards')
5 files changed, 134 insertions, 67 deletions
diff --git a/chromium/chrome/browser/ui/webui/discards/discards.mojom b/chromium/chrome/browser/ui/webui/discards/discards.mojom index aec7bd7dcff..1b54372b1cb 100644 --- a/chromium/chrome/browser/ui/webui/discards/discards.mojom +++ b/chromium/chrome/browser/ui/webui/discards/discards.mojom @@ -9,14 +9,16 @@ import "mojo/public/mojom/base/process_id.mojom"; import "mojo/public/mojom/base/time.mojom"; import "url/mojom/url.mojom"; -// Identical to content::Visibility. +// Identical to content::Visibility. Sent from browser to the chrome://discards +// WebUI. enum LifecycleUnitVisibility { HIDDEN = 0, OCCLUDED = 1, VISIBLE = 2, }; -// Discard related information about a single tab in a browser. +// Discard related information about a single tab in a browser. Sent from +// browser to the chrome://discards WebUI. struct TabDiscardsInfo { // The URL associated with the tab. This corresponds to GetLastCommittedURL, // and is also what is visible in the Omnibox for a given tab. @@ -29,10 +31,6 @@ struct TabDiscardsInfo { mojom.LifecycleUnitLoadingState loading_state; // The state of the LifecycleUnit. mojom.LifecycleUnitState state; - // Whether the tab can be frozen. - bool can_freeze; - // List of human-readable reasons why a tab can't be frozen. - array<string> cannot_freeze_reasons; // Whether the tab can be discarded. bool can_discard; // List of human-readable reasons why a tab can't be discarded. @@ -85,9 +83,6 @@ interface DetailsProvider { // Invokes a callback when the discard is complete. DiscardById(int32 tab_id) => (); - // Freezes a tab given its |tab_id|. - FreezeById(int32 tab_id); - // Loads a tab given its |tab_id|. LoadById(int32 tab_id); @@ -98,12 +93,16 @@ interface DetailsProvider { Discard() => (); }; -// Represents the momentary state of a Page node. +// Represents the momentary state of a Page node. Sent from browser to the +// chrome://discards WebUI via the GraphChangeStream (defined below). struct PageInfo { int64 id; url.mojom.Url main_frame_url; + // The id of the frame that "opened" this page, if any. + int64 opener_frame_id; + // This field is a dictionary of values, where each value is generated by // a performance_manager::NodeDataDescriber implementation and keyed by the // name it registered with. The intent is for each describer to describe @@ -112,46 +111,74 @@ struct PageInfo { string description_json; }; -// Represents the momentary state of a Frame node. +// Represents the momentary state of a Frame node. Sent from browser to the +// chrome://discards WebUI via the GraphChangeStream (defined below). struct FrameInfo { int64 id; + // The last committed URL of this frame. url.mojom.Url url; + + // The ID of the page node this frame is associated with. int64 page_id; + + // The ID of the parent frame, if there is one. If not, this is a main frame. int64 parent_frame_id; + + // The ID of the process in which this frame is hosted. int64 process_id; // See PageInfo::description_json. string description_json; }; -// Represents the momentary state of a Process node. +// Represents the momentary state of a Process node. Sent from browser to the +// chrome://discards WebUI via the GraphChangeStream (defined below). struct ProcessInfo { int64 id; + // The PID of the process associated with this node. mojo_base.mojom.ProcessId pid; + + // The private memory usage of this process in KB. uint64 private_footprint_kb; // See PageInfo::description_json. string description_json; }; -// Represents the momentary state of a Worker node. +// Represents the momentary state of a Worker node. Sent from browser to the +// chrome://discards WebUI via the GraphChangeStream (defined below). struct WorkerInfo { int64 id; + // The URL of the worker. url.mojom.Url url; + + // The ID of the process is which this worker is hosted. int64 process_id; + // An array of frames (by ID) that are clients of this worker (the worker is + // doing work on behalf of this frame). See + // WorkerNode::GetClientFrames() for details. array<int64> client_frame_ids; + + // An array of other workers (by ID) that are clients of this worker (the + // worker is doing work on behalf of these other workers). See + // WorkerNode::GetClientWorkers() for details. array<int64> client_worker_ids; + + // An array of workers (by ID) that are children of this worker. This can + // occur with shared and service workers owning their own dedicated workers. + // See WorkerNode::GetChildWorkers() for details. array<int64> child_worker_ids; // See PageInfo::description_json. string description_json; }; -// Used to transport favicon data. +// Used to transport favicon data. Sent from browser to the chrome://discards +// WebUI via the GraphChangeStream (defined below). struct FavIconInfo { int64 node_id; @@ -161,7 +188,11 @@ struct FavIconInfo { }; // Implement to receive a stream of notifications when performance manager -// graph nodes are created, changed or deleted. +// graph nodes are created, changed or deleted. Implemented in Javascript code +// running in the chrome://discards WebUI, with data routed to it from an +// observer of the performance_manager::Graph in the browser. The implementation +// is injected into the browser via the browser-exposed GraphDump interface, +// defined below. interface GraphChangeStream { // The |frame| was created. FrameCreated(FrameInfo frame); @@ -190,7 +221,8 @@ interface GraphChangeStream { }; // This interface allows subscribing to a stream of events that track the state -// of the performance manager graph. +// of the performance manager graph. Implemented in browser code, and used from +// Javascript code running in the chrome://discards WebUI. interface GraphDump { // Subscribes |change_subscriber| to a graph change stream. SubscribeToChanges(pending_remote<GraphChangeStream> change_subscriber); diff --git a/chromium/chrome/browser/ui/webui/discards/discards_ui.cc b/chromium/chrome/browser/ui/webui/discards/discards_ui.cc index fdbf79d7a00..95448e0d72c 100644 --- a/chromium/chrome/browser/ui/webui/discards/discards_ui.cc +++ b/chromium/chrome/browser/ui/webui/discards/discards_ui.cc @@ -41,6 +41,7 @@ #include "content/public/browser/web_ui_message_handler.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/receiver.h" +#include "services/network/public/mojom/content_security_policy.mojom.h" #include "ui/resources/grit/ui_resources.h" #include "url/gurl.h" #include "url/origin.h" @@ -133,9 +134,6 @@ class DiscardsDetailsProviderImpl : public discards::mojom::DetailsProvider { GetLifecycleUnitVisibility(lifecycle_unit->GetVisibility()); info->loading_state = lifecycle_unit->GetLoadingState(); info->state = lifecycle_unit->GetState(); - resource_coordinator::DecisionDetails freeze_details; - info->can_freeze = lifecycle_unit->CanFreeze(&freeze_details); - info->cannot_freeze_reasons = freeze_details.GetFailureReasonStrings(); resource_coordinator::DecisionDetails discard_details; info->cannot_discard_reasons = discard_details.GetFailureReasonStrings(); info->discard_reason = lifecycle_unit->GetDiscardReason(); @@ -193,12 +191,6 @@ class DiscardsDetailsProviderImpl : public discards::mojom::DetailsProvider { std::move(callback).Run(); } - void FreezeById(int32_t id) override { - auto* lifecycle_unit = GetLifecycleUnitById(id); - if (lifecycle_unit) - lifecycle_unit->Freeze(); - } - void LoadById(int32_t id) override { auto* lifecycle_unit = GetLifecycleUnitById(id); if (lifecycle_unit) @@ -225,7 +217,8 @@ DiscardsUI::DiscardsUI(content::WebUI* web_ui) std::unique_ptr<content::WebUIDataSource> source( content::WebUIDataSource::Create(chrome::kChromeUIDiscardsHost)); - source->OverrideContentSecurityPolicyScriptSrc( + source->OverrideContentSecurityPolicy( + network::mojom::CSPDirectiveName::ScriptSrc, "script-src chrome://resources chrome://test 'self';"); source->AddResourcePath("discards.js", IDR_DISCARDS_JS); diff --git a/chromium/chrome/browser/ui/webui/discards/graph_dump_impl.cc b/chromium/chrome/browser/ui/webui/discards/graph_dump_impl.cc index 2cb540e1ebb..9351afb96c9 100644 --- a/chromium/chrome/browser/ui/webui/discards/graph_dump_impl.cc +++ b/chromium/chrome/browser/ui/webui/discards/graph_dump_impl.cc @@ -12,7 +12,6 @@ #include "base/json/json_string_value_serializer.h" #include "base/macros.h" #include "base/task/cancelable_task_tracker.h" -#include "base/task/post_task.h" #include "base/threading/sequenced_task_runner_handle.h" #include "chrome/browser/favicon/favicon_service_factory.h" #include "chrome/browser/profiles/profile.h" @@ -193,31 +192,18 @@ void DiscardsGraphDumpImpl::SubscribeToChanges( } // Send creation notifications for all existing nodes. - for (const performance_manager::ProcessNode* process_node : - graph_->GetAllProcessNodes()) - SendProcessNotification(process_node, true); - - for (const performance_manager::PageNode* page_node : - graph_->GetAllPageNodes()) { - SendPageNotification(page_node, true); - StartPageFaviconRequest(page_node); - - // Dispatch preorder frame notifications. - for (const performance_manager::FrameNode* main_frame_node : - page_node->GetMainFrameNodes()) { - ForFrameAndOffspring( - main_frame_node, - [this](const performance_manager::FrameNode* frame_node) { - this->SendFrameNotification(frame_node, true); - this->StartFrameFaviconRequest(frame_node); - }); - } - } - - for (const performance_manager::WorkerNode* worker_node : - graph_->GetAllWorkerNodes()) { - SendWorkerNotification(worker_node, true); - } + SendNotificationToAllNodes(/* created = */ true); + + // It is entirely possible for there to be circular link references between + // nodes that already existed at the point this object was created (the loop + // was closed after the two nodes themselves were created). We don't have the + // exact order of historical events that led to the current graph state, so we + // simply fire off a node changed notification for all nodes after the node + // creation. This ensures that all targets exist the second time through, and + // any loops are closed. Afterwards any newly created loops will be properly + // maintained as node creation/destruction/link events will be fed to the + // graph in the proper order. + SendNotificationToAllNodes(/* created = */ false); // Subscribe to subsequent notifications. graph_->AddFrameNodeObserver(this); @@ -265,8 +251,8 @@ void DiscardsGraphDumpImpl::OnTakenFromGraph( // The favicon helper must be deleted on the UI thread. if (favicon_request_helper_) { - base::DeleteSoon(FROM_HERE, {content::BrowserThread::UI}, - std::move(favicon_request_helper_)); + content::GetUIThreadTaskRunner({})->DeleteSoon( + FROM_HERE, std::move(favicon_request_helper_)); } graph_ = nullptr; @@ -305,6 +291,14 @@ void DiscardsGraphDumpImpl::OnBeforePageNodeRemoved( RemoveNode(page_node); } +void DiscardsGraphDumpImpl::OnOpenerFrameNodeChanged( + const performance_manager::PageNode* page_node, + const performance_manager::FrameNode*, + OpenedType) { + DCHECK(HasNode(page_node)); + SendPageNotification(page_node, false); +} + void DiscardsGraphDumpImpl::OnFaviconUpdated( const performance_manager::PageNode* page_node) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); @@ -391,13 +385,19 @@ void DiscardsGraphDumpImpl::RemoveNode(const performance_manager::Node* node) { DCHECK_EQ(1u, erased); } +bool DiscardsGraphDumpImpl::HasNode( + const performance_manager::Node* node) const { + return node_ids_.find(node) != node_ids_.end(); +} + int64_t DiscardsGraphDumpImpl::GetNodeId( - const performance_manager::Node* node) { + const performance_manager::Node* node) const { if (node == nullptr) return 0; - DCHECK(node_ids_.find(node) != node_ids_.end()); - return node_ids_[node].GetUnsafeValue(); + auto it = node_ids_.find(node); + DCHECK(it != node_ids_.end()); + return it->second.GetUnsafeValue(); } DiscardsGraphDumpImpl::FaviconRequestHelper* @@ -416,8 +416,8 @@ void DiscardsGraphDumpImpl::StartPageFaviconRequest( if (!page_node->GetMainFrameUrl().is_valid()) return; - base::PostTask( - FROM_HERE, {content::BrowserThread::UI}, + content::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&FaviconRequestHelper::RequestFavicon, base::Unretained(EnsureFaviconRequestHelper()), page_node->GetMainFrameUrl(), @@ -429,14 +429,44 @@ void DiscardsGraphDumpImpl::StartFrameFaviconRequest( if (!frame_node->GetURL().is_valid()) return; - base::PostTask(FROM_HERE, {content::BrowserThread::UI}, - base::BindOnce(&FaviconRequestHelper::RequestFavicon, + content::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&FaviconRequestHelper::RequestFavicon, base::Unretained(EnsureFaviconRequestHelper()), frame_node->GetURL(), frame_node->GetPageNode()->GetContentsProxy(), GetNodeId(frame_node))); } +void DiscardsGraphDumpImpl::SendNotificationToAllNodes(bool created) { + for (const performance_manager::ProcessNode* process_node : + graph_->GetAllProcessNodes()) + SendProcessNotification(process_node, created); + + for (const performance_manager::PageNode* page_node : + graph_->GetAllPageNodes()) { + SendPageNotification(page_node, created); + if (created) + StartPageFaviconRequest(page_node); + + // Dispatch preorder frame notifications. + for (const performance_manager::FrameNode* main_frame_node : + page_node->GetMainFrameNodes()) { + ForFrameAndOffspring( + main_frame_node, + [this, created](const performance_manager::FrameNode* frame_node) { + this->SendFrameNotification(frame_node, created); + if (created) + this->StartFrameFaviconRequest(frame_node); + }); + } + } + + for (const performance_manager::WorkerNode* worker_node : + graph_->GetAllWorkerNodes()) { + SendWorkerNotification(worker_node, created); + } +} + void DiscardsGraphDumpImpl::SendFrameNotification( const performance_manager::FrameNode* frame, bool created) { @@ -459,10 +489,11 @@ void DiscardsGraphDumpImpl::SendFrameNotification( frame_info->description_json = ToJSON(graph_->GetNodeDataDescriberRegistry()->DescribeNodeData(frame)); - if (created) + if (created) { change_subscriber_->FrameCreated(std::move(frame_info)); - else + } else { change_subscriber_->FrameChanged(std::move(frame_info)); + } } void DiscardsGraphDumpImpl::SendPageNotification( @@ -474,6 +505,7 @@ void DiscardsGraphDumpImpl::SendPageNotification( page_info->id = GetNodeId(page_node); page_info->main_frame_url = page_node->GetMainFrameUrl(); + page_info->opener_frame_id = GetNodeId(page_node->GetOpenerFrameNode()); page_info->description_json = ToJSON( graph_->GetNodeDataDescriberRegistry()->DescribeNodeData(page_node)); diff --git a/chromium/chrome/browser/ui/webui/discards/graph_dump_impl.h b/chromium/chrome/browser/ui/webui/discards/graph_dump_impl.h index 893d7f3faec..de771acc112 100644 --- a/chromium/chrome/browser/ui/webui/discards/graph_dump_impl.h +++ b/chromium/chrome/browser/ui/webui/discards/graph_dump_impl.h @@ -99,6 +99,9 @@ class DiscardsGraphDumpImpl : public discards::mojom::GraphDump, void OnHadFormInteractionChanged( const performance_manager::FrameNode* frame_node) override {} // Ignored. + void OnIsAudibleChanged( + const performance_manager::FrameNode* frame_node) override {} + // Ignored. void OnFirstContentfulPaint( const performance_manager::FrameNode* frame_node, base::TimeDelta time_since_navigation_start) override {} @@ -107,6 +110,10 @@ class DiscardsGraphDumpImpl : public discards::mojom::GraphDump, void OnPageNodeAdded(const performance_manager::PageNode* page_node) override; void OnBeforePageNodeRemoved( const performance_manager::PageNode* page_node) override; + void OnOpenerFrameNodeChanged( + const performance_manager::PageNode* page_node, + const performance_manager::FrameNode* previous_opener, + OpenedType previous_opened_type) override; void OnIsVisibleChanged( const performance_manager::PageNode* page_node) override {} // Ignored. void OnIsAudibleChanged( @@ -186,7 +193,8 @@ class DiscardsGraphDumpImpl : public discards::mojom::GraphDump, void AddNode(const performance_manager::Node* node); void RemoveNode(const performance_manager::Node* node); - int64_t GetNodeId(const performance_manager::Node* node); + bool HasNode(const performance_manager::Node* node) const; + int64_t GetNodeId(const performance_manager::Node* node) const; FaviconRequestHelper* EnsureFaviconRequestHelper(); @@ -194,6 +202,7 @@ class DiscardsGraphDumpImpl : public discards::mojom::GraphDump, void StartFrameFaviconRequest( const performance_manager::FrameNode* frame_node); + void SendNotificationToAllNodes(bool created); void SendFrameNotification(const performance_manager::FrameNode* frame, bool created); void SendPageNotification(const performance_manager::PageNode* page, diff --git a/chromium/chrome/browser/ui/webui/discards/graph_dump_impl_unittest.cc b/chromium/chrome/browser/ui/webui/discards/graph_dump_impl_unittest.cc index 32c220349fb..e554f7d7a8d 100644 --- a/chromium/chrome/browser/ui/webui/discards/graph_dump_impl_unittest.cc +++ b/chromium/chrome/browser/ui/webui/discards/graph_dump_impl_unittest.cc @@ -212,8 +212,9 @@ TEST_F(DiscardsGraphDumpImplTest, ChangeStream) { task_environment.RunUntilIdle(); - // Validate that the initial graph state dump is complete. - EXPECT_EQ(0u, change_stream.num_changes()); + // Validate that the initial graph state dump is complete. Note that there is + // an update for each node as part of the initial state dump. + EXPECT_EQ(8u, change_stream.num_changes()); EXPECT_EQ(8u, change_stream.id_set().size()); EXPECT_EQ(2u, change_stream.process_map().size()); @@ -277,7 +278,7 @@ TEST_F(DiscardsGraphDumpImplTest, ChangeStream) { task_environment.RunUntilIdle(); // Main frame navigation results in a notification for the url. - EXPECT_EQ(1u, change_stream.num_changes()); + EXPECT_EQ(9u, change_stream.num_changes()); EXPECT_FALSE(base::Contains(change_stream.id_set(), child_frame_id)); const auto main_page_it = change_stream.page_map().find( |