summaryrefslogtreecommitdiff
path: root/chromium/chrome/browser/ui/webui/discards
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2020-10-12 14:27:29 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2020-10-13 09:35:20 +0000
commitc30a6232df03e1efbd9f3b226777b07e087a1122 (patch)
treee992f45784689f373bcc38d1b79a239ebe17ee23 /chromium/chrome/browser/ui/webui/discards
parent7b5b123ac58f58ffde0f4f6e488bcd09aa4decd3 (diff)
downloadqtwebengine-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')
-rw-r--r--chromium/chrome/browser/ui/webui/discards/discards.mojom64
-rw-r--r--chromium/chrome/browser/ui/webui/discards/discards_ui.cc13
-rw-r--r--chromium/chrome/browser/ui/webui/discards/graph_dump_impl.cc106
-rw-r--r--chromium/chrome/browser/ui/webui/discards/graph_dump_impl.h11
-rw-r--r--chromium/chrome/browser/ui/webui/discards/graph_dump_impl_unittest.cc7
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(