Commit 9419eeed authored by Avi Drissman's avatar Avi Drissman Committed by Commit Bot

Remove raw pointers from WebContentsTags and Tasks

task_manager::WebContentsTag::CreateTask returns ownership in a
raw pointer. Fix that. WebContentsTaskProvider::WebContentsEntry
then has to juggle those raw pointers. Fix that.

Bug: none
Change-Id: Ie19f3f67365b8f1ff22079949a6148f058d7ffd4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2361204
Commit-Queue: Avi Drissman <avi@chromium.org>
Auto-Submit: Avi Drissman <avi@chromium.org>
Reviewed-by: default avatarAhmed Fakhry <afakhry@chromium.org>
Cr-Commit-Position: refs/heads/master@{#799819}
parent 283a7728
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
#include "chrome/browser/task_manager/providers/web_contents/background_contents_tag.h" #include "chrome/browser/task_manager/providers/web_contents/background_contents_tag.h"
#include <memory>
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "chrome/browser/background/background_contents.h" #include "chrome/browser/background/background_contents.h"
#include "chrome/browser/background/background_contents_service.h" #include "chrome/browser/background/background_contents_service.h"
...@@ -17,7 +19,7 @@ ...@@ -17,7 +19,7 @@
namespace task_manager { namespace task_manager {
BackgroundContentsTask* BackgroundContentsTag::CreateTask( std::unique_ptr<RendererTask> BackgroundContentsTag::CreateTask(
WebContentsTaskProvider*) const { WebContentsTaskProvider*) const {
// Try to lookup the application name from the parent extension (if any). // Try to lookup the application name from the parent extension (if any).
Profile* profile = Profile::FromBrowserContext( Profile* profile = Profile::FromBrowserContext(
...@@ -34,7 +36,8 @@ BackgroundContentsTask* BackgroundContentsTag::CreateTask( ...@@ -34,7 +36,8 @@ BackgroundContentsTask* BackgroundContentsTag::CreateTask(
if (extension) if (extension)
application_name = base::UTF8ToUTF16(extension->name()); application_name = base::UTF8ToUTF16(extension->name());
return new BackgroundContentsTask(application_name, background_contents_); return std::make_unique<BackgroundContentsTask>(application_name,
background_contents_);
} }
BackgroundContentsTag::BackgroundContentsTag( BackgroundContentsTag::BackgroundContentsTag(
......
...@@ -20,7 +20,8 @@ class BackgroundContentsTag : public WebContentsTag { ...@@ -20,7 +20,8 @@ class BackgroundContentsTag : public WebContentsTag {
~BackgroundContentsTag() override; ~BackgroundContentsTag() override;
// task_manager::WebContentsTag: // task_manager::WebContentsTag:
BackgroundContentsTask* CreateTask(WebContentsTaskProvider*) const override; std::unique_ptr<RendererTask> CreateTask(
WebContentsTaskProvider*) const override;
private: private:
friend class WebContentsTags; friend class WebContentsTags;
......
...@@ -4,10 +4,13 @@ ...@@ -4,10 +4,13 @@
#include "chrome/browser/task_manager/providers/web_contents/devtools_tag.h" #include "chrome/browser/task_manager/providers/web_contents/devtools_tag.h"
#include <memory>
namespace task_manager { namespace task_manager {
DevToolsTask* DevToolsTag::CreateTask(WebContentsTaskProvider*) const { std::unique_ptr<RendererTask> DevToolsTag::CreateTask(
return new DevToolsTask(web_contents()); WebContentsTaskProvider*) const {
return std::make_unique<DevToolsTask>(web_contents());
} }
DevToolsTag::DevToolsTag(content::WebContents* web_contents) DevToolsTag::DevToolsTag(content::WebContents* web_contents)
......
...@@ -17,7 +17,8 @@ class DevToolsTag : public WebContentsTag { ...@@ -17,7 +17,8 @@ class DevToolsTag : public WebContentsTag {
~DevToolsTag() override; ~DevToolsTag() override;
// task_manager::WebContentsTag: // task_manager::WebContentsTag:
DevToolsTask* CreateTask(WebContentsTaskProvider*) const override; std::unique_ptr<RendererTask> CreateTask(
WebContentsTaskProvider*) const override;
private: private:
friend class WebContentsTags; friend class WebContentsTags;
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
#include "chrome/browser/task_manager/providers/web_contents/extension_tag.h" #include "chrome/browser/task_manager/providers/web_contents/extension_tag.h"
#include <memory>
#include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents.h"
#include "extensions/buildflags/buildflags.h" #include "extensions/buildflags/buildflags.h"
...@@ -13,7 +15,8 @@ ...@@ -13,7 +15,8 @@
namespace task_manager { namespace task_manager {
ExtensionTask* ExtensionTag::CreateTask(WebContentsTaskProvider*) const { std::unique_ptr<RendererTask> ExtensionTag::CreateTask(
WebContentsTaskProvider*) const {
// Upon being asked to create a task, it means that the site instance is ready // Upon being asked to create a task, it means that the site instance is ready
// and connected, and the render frames have been initialized. // and connected, and the render frames have been initialized.
// It's OK if the following returns nullptr, ExtensionTask will then get the // It's OK if the following returns nullptr, ExtensionTask will then get the
...@@ -22,7 +25,7 @@ ExtensionTask* ExtensionTag::CreateTask(WebContentsTaskProvider*) const { ...@@ -22,7 +25,7 @@ ExtensionTask* ExtensionTag::CreateTask(WebContentsTaskProvider*) const {
extensions::ProcessManager::Get(web_contents()->GetBrowserContext())-> extensions::ProcessManager::Get(web_contents()->GetBrowserContext())->
GetExtensionForWebContents(web_contents()); GetExtensionForWebContents(web_contents());
return new ExtensionTask(web_contents(), extension, view_type_); return std::make_unique<ExtensionTask>(web_contents(), extension, view_type_);
} }
ExtensionTag::ExtensionTag(content::WebContents* web_contents, ExtensionTag::ExtensionTag(content::WebContents* web_contents,
......
...@@ -17,7 +17,8 @@ class ExtensionTag : public WebContentsTag { ...@@ -17,7 +17,8 @@ class ExtensionTag : public WebContentsTag {
~ExtensionTag() override; ~ExtensionTag() override;
// task_manager::WebContentsTag: // task_manager::WebContentsTag:
ExtensionTask* CreateTask(WebContentsTaskProvider*) const override; std::unique_ptr<RendererTask> CreateTask(
WebContentsTaskProvider*) const override;
private: private:
friend class WebContentsTags; friend class WebContentsTags;
......
...@@ -4,10 +4,13 @@ ...@@ -4,10 +4,13 @@
#include "chrome/browser/task_manager/providers/web_contents/guest_tag.h" #include "chrome/browser/task_manager/providers/web_contents/guest_tag.h"
#include <memory>
namespace task_manager { namespace task_manager {
GuestTask* GuestTag::CreateTask(WebContentsTaskProvider*) const { std::unique_ptr<RendererTask> GuestTag::CreateTask(
return new GuestTask(web_contents()); WebContentsTaskProvider*) const {
return std::make_unique<GuestTask>(web_contents());
} }
GuestTag::GuestTag(content::WebContents* web_contents) GuestTag::GuestTag(content::WebContents* web_contents)
......
...@@ -18,7 +18,8 @@ class GuestTag : public WebContentsTag { ...@@ -18,7 +18,8 @@ class GuestTag : public WebContentsTag {
~GuestTag() override; ~GuestTag() override;
// task_manager::WebContentsTag: // task_manager::WebContentsTag:
GuestTask* CreateTask(WebContentsTaskProvider*) const override; std::unique_ptr<RendererTask> CreateTask(
WebContentsTaskProvider*) const override;
private: private:
friend class WebContentsTags; friend class WebContentsTags;
......
...@@ -4,11 +4,13 @@ ...@@ -4,11 +4,13 @@
#include "chrome/browser/task_manager/providers/web_contents/portal_tag.h" #include "chrome/browser/task_manager/providers/web_contents/portal_tag.h"
#include <memory>
namespace task_manager { namespace task_manager {
PortalTask* PortalTag::CreateTask( std::unique_ptr<RendererTask> PortalTag::CreateTask(
WebContentsTaskProvider* task_provider) const { WebContentsTaskProvider* task_provider) const {
return new PortalTask(web_contents(), task_provider); return std::make_unique<PortalTask>(web_contents(), task_provider);
} }
PortalTag::PortalTag(content::WebContents* web_contents) PortalTag::PortalTag(content::WebContents* web_contents)
......
...@@ -19,7 +19,8 @@ class PortalTag : public WebContentsTag { ...@@ -19,7 +19,8 @@ class PortalTag : public WebContentsTag {
~PortalTag() override; ~PortalTag() override;
// task_manager::WebContentsTag: // task_manager::WebContentsTag:
PortalTask* CreateTask(WebContentsTaskProvider* task_provider) const override; std::unique_ptr<RendererTask> CreateTask(
WebContentsTaskProvider* task_provider) const override;
private: private:
friend class WebContentsTags; friend class WebContentsTags;
......
...@@ -4,10 +4,13 @@ ...@@ -4,10 +4,13 @@
#include "chrome/browser/task_manager/providers/web_contents/prerender_tag.h" #include "chrome/browser/task_manager/providers/web_contents/prerender_tag.h"
#include <memory>
namespace task_manager { namespace task_manager {
PrerenderTask* PrerenderTag::CreateTask(WebContentsTaskProvider*) const { std::unique_ptr<RendererTask> PrerenderTag::CreateTask(
return new PrerenderTask(web_contents()); WebContentsTaskProvider*) const {
return std::make_unique<PrerenderTask>(web_contents());
} }
PrerenderTag::PrerenderTag(content::WebContents* web_contents) PrerenderTag::PrerenderTag(content::WebContents* web_contents)
......
...@@ -18,7 +18,8 @@ class PrerenderTag : public WebContentsTag { ...@@ -18,7 +18,8 @@ class PrerenderTag : public WebContentsTag {
~PrerenderTag() override; ~PrerenderTag() override;
// task_manager::WebContentsTag: // task_manager::WebContentsTag:
PrerenderTask* CreateTask(WebContentsTaskProvider*) const override; std::unique_ptr<RendererTask> CreateTask(
WebContentsTaskProvider*) const override;
private: private:
friend class WebContentsTags; friend class WebContentsTags;
......
...@@ -4,10 +4,13 @@ ...@@ -4,10 +4,13 @@
#include "chrome/browser/task_manager/providers/web_contents/printing_tag.h" #include "chrome/browser/task_manager/providers/web_contents/printing_tag.h"
#include <memory>
namespace task_manager { namespace task_manager {
PrintingTask* PrintingTag::CreateTask(WebContentsTaskProvider*) const { std::unique_ptr<RendererTask> PrintingTag::CreateTask(
return new PrintingTask(web_contents()); WebContentsTaskProvider*) const {
return std::make_unique<PrintingTask>(web_contents());
} }
PrintingTag::PrintingTag(content::WebContents* web_contents) PrintingTag::PrintingTag(content::WebContents* web_contents)
......
...@@ -18,7 +18,8 @@ class PrintingTag : public WebContentsTag { ...@@ -18,7 +18,8 @@ class PrintingTag : public WebContentsTag {
~PrintingTag() override; ~PrintingTag() override;
// task_manager::WebContentsTag: // task_manager::WebContentsTag:
PrintingTask* CreateTask(WebContentsTaskProvider*) const override; std::unique_ptr<RendererTask> CreateTask(
WebContentsTaskProvider*) const override;
private: private:
friend class WebContentsTags; friend class WebContentsTags;
......
...@@ -4,10 +4,13 @@ ...@@ -4,10 +4,13 @@
#include "chrome/browser/task_manager/providers/web_contents/tab_contents_tag.h" #include "chrome/browser/task_manager/providers/web_contents/tab_contents_tag.h"
#include <memory>
namespace task_manager { namespace task_manager {
TabContentsTask* TabContentsTag::CreateTask(WebContentsTaskProvider*) const { std::unique_ptr<RendererTask> TabContentsTag::CreateTask(
return new TabContentsTask(web_contents()); WebContentsTaskProvider*) const {
return std::make_unique<TabContentsTask>(web_contents());
} }
TabContentsTag::TabContentsTag(content::WebContents* web_contents) TabContentsTag::TabContentsTag(content::WebContents* web_contents)
......
...@@ -17,7 +17,8 @@ class TabContentsTag : public WebContentsTag { ...@@ -17,7 +17,8 @@ class TabContentsTag : public WebContentsTag {
~TabContentsTag() override; ~TabContentsTag() override;
// task_manager::WebContentsTag: // task_manager::WebContentsTag:
TabContentsTask* CreateTask(WebContentsTaskProvider*) const override; std::unique_ptr<RendererTask> CreateTask(
WebContentsTaskProvider*) const override;
private: private:
friend class WebContentsTags; friend class WebContentsTags;
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
#ifndef CHROME_BROWSER_TASK_MANAGER_PROVIDERS_WEB_CONTENTS_WEB_CONTENTS_TAG_H_ #ifndef CHROME_BROWSER_TASK_MANAGER_PROVIDERS_WEB_CONTENTS_WEB_CONTENTS_TAG_H_
#define CHROME_BROWSER_TASK_MANAGER_PROVIDERS_WEB_CONTENTS_WEB_CONTENTS_TAG_H_ #define CHROME_BROWSER_TASK_MANAGER_PROVIDERS_WEB_CONTENTS_WEB_CONTENTS_TAG_H_
#include <memory>
#include "base/macros.h" #include "base/macros.h"
#include "base/supports_user_data.h" #include "base/supports_user_data.h"
...@@ -36,11 +38,9 @@ class WebContentsTag : public base::SupportsUserData::Data { ...@@ -36,11 +38,9 @@ class WebContentsTag : public base::SupportsUserData::Data {
// The concrete Tags know how to instantiate a |RendererTask| that corresponds // The concrete Tags know how to instantiate a |RendererTask| that corresponds
// to the owning WebContents and Service. This will be used by the // to the owning WebContents and Service. This will be used by the
// WebContentsTaskProvider to create the appropriate Tasks. // WebContentsTaskProvider to create the appropriate Tasks. |task_provicer| is
// // provided in case the task needs it for construction.
// The returned |RendererTask| is owned by the caller (in this case it will be virtual std::unique_ptr<RendererTask> CreateTask(
// the provider, |task_provider|).
virtual RendererTask* CreateTask(
WebContentsTaskProvider* task_provider) const = 0; WebContentsTaskProvider* task_provider) const = 0;
content::WebContents* web_contents() const { return web_contents_; } content::WebContents* web_contents() const { return web_contents_; }
......
...@@ -4,10 +4,13 @@ ...@@ -4,10 +4,13 @@
#include "chrome/browser/task_manager/providers/web_contents/web_contents_task_provider.h" #include "chrome/browser/task_manager/providers/web_contents/web_contents_task_provider.h"
#include <memory>
#include "base/bind.h" #include "base/bind.h"
#include "base/macros.h" #include "base/check.h"
#include "base/containers/flat_map.h"
#include "base/containers/flat_set.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "base/stl_util.h"
#include "chrome/browser/task_manager/providers/web_contents/subframe_task.h" #include "chrome/browser/task_manager/providers/web_contents/subframe_task.h"
#include "chrome/browser/task_manager/providers/web_contents/web_contents_tags_manager.h" #include "chrome/browser/task_manager/providers/web_contents/web_contents_tags_manager.h"
#include "content/public/browser/navigation_handle.h" #include "content/public/browser/navigation_handle.h"
...@@ -29,11 +32,14 @@ namespace task_manager { ...@@ -29,11 +32,14 @@ namespace task_manager {
// WebContents) of these events. // WebContents) of these events.
// The entry owns the created tasks representing the WebContents, and it is // The entry owns the created tasks representing the WebContents, and it is
// itself owned by the provider. // itself owned by the provider.
class WebContentsEntry : public content::WebContentsObserver { class WebContentsTaskProvider::WebContentsEntry
: public content::WebContentsObserver {
public: public:
WebContentsEntry(content::WebContents* web_contents, WebContentsEntry(content::WebContents* web_contents,
WebContentsTaskProvider* provider); WebContentsTaskProvider* provider);
~WebContentsEntry() override; ~WebContentsEntry() override;
WebContentsEntry(const WebContentsEntry&) = delete;
WebContentsEntry& operator=(const WebContentsEntry&) = delete;
// Creates all the tasks associated with each |RenderFrameHost| in this // Creates all the tasks associated with each |RenderFrameHost| in this
// entry's WebContents. // entry's WebContents.
...@@ -75,9 +81,6 @@ class WebContentsEntry : public content::WebContentsObserver { ...@@ -75,9 +81,6 @@ class WebContentsEntry : public content::WebContentsObserver {
// |ancestor|. // |ancestor|.
void ClearTasksForDescendantsOf(RenderFrameHost* ancestor); void ClearTasksForDescendantsOf(RenderFrameHost* ancestor);
// Calls |on_task| for each task managed by this WebContentsEntry.
void ForEachTask(const base::RepeatingCallback<void(RendererTask*)> on_task);
// Walks parents until hitting a process boundary. Returns the highest frame // Walks parents until hitting a process boundary. Returns the highest frame
// in the same SiteInstance as |render_frame_host|. // in the same SiteInstance as |render_frame_host|.
RenderFrameHost* FindLocalRoot(RenderFrameHost* render_frame_host) const; RenderFrameHost* FindLocalRoot(RenderFrameHost* render_frame_host) const;
...@@ -85,70 +88,68 @@ class WebContentsEntry : public content::WebContentsObserver { ...@@ -85,70 +88,68 @@ class WebContentsEntry : public content::WebContentsObserver {
// The provider that owns this entry. // The provider that owns this entry.
WebContentsTaskProvider* provider_; WebContentsTaskProvider* provider_;
// The RenderFrameHosts associated with this entry's WebContents that we're // For each SiteInstance, the frames within it that are tracked (local roots
// tracking mapped by their SiteInstances. // only as per FindLocalRoot()), and its RendererTask. The number of tracked
using FramesList = std::vector<RenderFrameHost*>; // items is small, thus flat_map and flat_set.
std::map<SiteInstance*, FramesList> frames_by_site_instance_; struct SiteInstanceInfo {
base::flat_set<RenderFrameHost*> frames;
// The RendererTasks that we create for the task manager, mapped by their std::unique_ptr<RendererTask> renderer_task;
// RenderFrameHosts. This owns the RenderTasks. };
std::map<RenderFrameHost*, RendererTask*> tasks_by_frames_; base::flat_map<SiteInstance*, SiteInstanceInfo> site_instance_infos_;
// States whether we did record a main frame for this entry. // States whether we did record a main frame for this entry.
SiteInstance* main_frame_site_instance_; SiteInstance* main_frame_site_instance_ = nullptr;
base::WeakPtrFactory<WebContentsEntry> weak_factory_{this}; base::WeakPtrFactory<WebContentsEntry> weak_factory_{this};
DISALLOW_COPY_AND_ASSIGN(WebContentsEntry);
}; };
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
WebContentsEntry::WebContentsEntry(content::WebContents* web_contents, WebContentsTaskProvider::WebContentsEntry::WebContentsEntry(
WebContentsTaskProvider* provider) content::WebContents* web_contents,
: WebContentsObserver(web_contents), WebContentsTaskProvider* provider)
provider_(provider), : WebContentsObserver(web_contents), provider_(provider) {}
main_frame_site_instance_(nullptr) {}
WebContentsEntry::~WebContentsEntry() { WebContentsTaskProvider::WebContentsEntry::~WebContentsEntry() {
ClearAllTasks(false); ClearAllTasks(false);
} }
void WebContentsEntry::CreateAllTasks() { void WebContentsTaskProvider::WebContentsEntry::CreateAllTasks() {
DCHECK(web_contents()->GetMainFrame()); DCHECK(web_contents()->GetMainFrame());
web_contents()->ForEachFrame(base::BindRepeating( web_contents()->ForEachFrame(base::BindRepeating(
&WebContentsEntry::CreateTaskForFrame, base::Unretained(this))); &WebContentsEntry::CreateTaskForFrame, base::Unretained(this)));
} }
void WebContentsEntry::ClearAllTasks(bool notify_observer) { void WebContentsTaskProvider::WebContentsEntry::ClearAllTasks(
ForEachTask(base::BindRepeating( bool notify_observer) {
[](WebContentsTaskProvider* provider, bool notify_observer, for (auto& it : site_instance_infos_) {
content::WebContents* web_contents, RendererTask* task) { RendererTask* task = it.second.renderer_task.get();
task->set_termination_status(web_contents->GetCrashedStatus()); task->set_termination_status(web_contents()->GetCrashedStatus());
task->set_termination_error_code(web_contents->GetCrashedErrorCode()); task->set_termination_error_code(web_contents()->GetCrashedErrorCode());
if (notify_observer) if (notify_observer)
provider->NotifyObserverTaskRemoved(task); provider_->NotifyObserverTaskRemoved(task);
delete task; }
},
provider_, notify_observer, web_contents())); site_instance_infos_.clear();
frames_by_site_instance_.clear();
tasks_by_frames_.clear();
main_frame_site_instance_ = nullptr; main_frame_site_instance_ = nullptr;
} }
RendererTask* WebContentsEntry::GetTaskForFrame( RendererTask* WebContentsTaskProvider::WebContentsEntry::GetTaskForFrame(
RenderFrameHost* render_frame_host) const { RenderFrameHost* render_frame_host) const {
// Only local roots are in |tasks_by_frames_|. SiteInstance* site_instance = render_frame_host->GetSiteInstance();
auto itr = tasks_by_frames_.find(FindLocalRoot(render_frame_host)); auto itr = site_instance_infos_.find(site_instance);
if (itr == tasks_by_frames_.end()) if (itr == site_instance_infos_.end())
return nullptr;
// Only local roots are in the frame list.
if (!itr->second.frames.count(render_frame_host))
return nullptr; return nullptr;
return itr->second; return itr->second.renderer_task.get();
} }
RenderFrameHost* WebContentsEntry::FindLocalRoot( RenderFrameHost* WebContentsTaskProvider::WebContentsEntry::FindLocalRoot(
RenderFrameHost* render_frame_host) const { RenderFrameHost* render_frame_host) const {
SiteInstance* site_instance = render_frame_host->GetSiteInstance(); SiteInstance* site_instance = render_frame_host->GetSiteInstance();
RenderFrameHost* candidate = render_frame_host; RenderFrameHost* candidate = render_frame_host;
...@@ -160,24 +161,29 @@ RenderFrameHost* WebContentsEntry::FindLocalRoot( ...@@ -160,24 +161,29 @@ RenderFrameHost* WebContentsEntry::FindLocalRoot(
return candidate; return candidate;
} }
void WebContentsEntry::RenderFrameDeleted(RenderFrameHost* render_frame_host) { void WebContentsTaskProvider::WebContentsEntry::RenderFrameDeleted(
RenderFrameHost* render_frame_host) {
ClearTaskForFrame(render_frame_host); ClearTaskForFrame(render_frame_host);
} }
void WebContentsEntry::RenderFrameHostChanged(RenderFrameHost* old_host, void WebContentsTaskProvider::WebContentsEntry::RenderFrameHostChanged(
RenderFrameHost* new_host) { RenderFrameHost* old_host,
RenderFrameHost* new_host) {
DCHECK(new_host->IsCurrent()); DCHECK(new_host->IsCurrent());
// The navigating frame and its subframes are now pending deletion. Stop // The navigating frame and its subframes are now pending deletion. Stop
// tracking them immediately rather than when they are destroyed. The order of // tracking them immediately rather than when they are destroyed. The order of
// deletion is important. The children must be removed first. // deletion is important. The children must be removed first.
ClearTasksForDescendantsOf(old_host); if (old_host) {
ClearTaskForFrame(old_host); ClearTasksForDescendantsOf(old_host);
ClearTaskForFrame(old_host);
}
CreateTaskForFrame(new_host); CreateTaskForFrame(new_host);
} }
void WebContentsEntry::RenderFrameCreated(RenderFrameHost* render_frame_host) { void WebContentsTaskProvider::WebContentsEntry::RenderFrameCreated(
RenderFrameHost* render_frame_host) {
DCHECK(render_frame_host->IsRenderFrameLive()); DCHECK(render_frame_host->IsRenderFrameLive());
// Skip pending/speculative hosts. We'll create tasks for these if the // Skip pending/speculative hosts. We'll create tasks for these if the
...@@ -188,8 +194,9 @@ void WebContentsEntry::RenderFrameCreated(RenderFrameHost* render_frame_host) { ...@@ -188,8 +194,9 @@ void WebContentsEntry::RenderFrameCreated(RenderFrameHost* render_frame_host) {
CreateTaskForFrame(render_frame_host); CreateTaskForFrame(render_frame_host);
} }
void WebContentsEntry::RenderFrameReady(int render_process_id, void WebContentsTaskProvider::WebContentsEntry::RenderFrameReady(
int render_frame_id) { int render_process_id,
int render_frame_id) {
// We get here when a RenderProcessHost we are tracking transitions to the // We get here when a RenderProcessHost we are tracking transitions to the
// IsReady state. This might mean we know its process ID. // IsReady state. This might mean we know its process ID.
content::RenderFrameHost* render_frame_host = content::RenderFrameHost* render_frame_host =
...@@ -208,28 +215,23 @@ void WebContentsEntry::RenderFrameReady(int render_process_id, ...@@ -208,28 +215,23 @@ void WebContentsEntry::RenderFrameReady(int render_process_id,
determine_pid_from_handle); determine_pid_from_handle);
} }
void WebContentsEntry::WebContentsDestroyed() { void WebContentsTaskProvider::WebContentsEntry::WebContentsDestroyed() {
ClearAllTasks(true); ClearAllTasks(true);
provider_->DeleteEntry(web_contents()); provider_->DeleteEntry(web_contents());
} }
void WebContentsEntry::OnRendererUnresponsive( void WebContentsTaskProvider::WebContentsEntry::OnRendererUnresponsive(
RenderProcessHost* render_process_host) { RenderProcessHost* render_process_host) {
// Find the first RenderFrameHost matching the RenderProcessHost. for (const auto& pair : site_instance_infos_) {
RendererTask* task = nullptr;
for (const auto& pair : tasks_by_frames_) {
if (pair.first->GetProcess() == render_process_host) { if (pair.first->GetProcess() == render_process_host) {
task = pair.second; provider_->NotifyObserverTaskUnresponsive(
break; pair.second.renderer_task.get());
return;
} }
} }
if (!task)
return;
provider_->NotifyObserverTaskUnresponsive(task);
} }
void WebContentsEntry::DidFinishNavigation( void WebContentsTaskProvider::WebContentsEntry::DidFinishNavigation(
content::NavigationHandle* navigation_handle) { content::NavigationHandle* navigation_handle) {
// We only need to update tasks for main frame navigations. // We only need to update tasks for main frame navigations.
if (!navigation_handle->IsInMainFrame()) if (!navigation_handle->IsInMainFrame())
...@@ -240,7 +242,9 @@ void WebContentsEntry::DidFinishNavigation( ...@@ -240,7 +242,9 @@ void WebContentsEntry::DidFinishNavigation(
if (!main_frame_task) if (!main_frame_task)
return; return;
ForEachTask(base::BindRepeating([](RendererTask* task) { for (auto& it : site_instance_infos_) {
RendererTask* task = it.second.renderer_task.get();
// Listening to WebContentsObserver::TitleWasSet() only is not enough in // Listening to WebContentsObserver::TitleWasSet() only is not enough in
// some cases when the the web page doesn't have a title. That's why we // some cases when the the web page doesn't have a title. That's why we
// update the title here as well. // update the title here as well.
...@@ -251,41 +255,41 @@ void WebContentsEntry::DidFinishNavigation( ...@@ -251,41 +255,41 @@ void WebContentsEntry::DidFinishNavigation(
// RendererTask::OnFaviconUpdated() will update the current favicon once // RendererTask::OnFaviconUpdated() will update the current favicon once
// FaviconDriver figures out the correct favicon for the page. // FaviconDriver figures out the correct favicon for the page.
task->UpdateFavicon(); task->UpdateFavicon();
})); }
} }
void WebContentsEntry::TitleWasSet(content::NavigationEntry* entry) { void WebContentsTaskProvider::WebContentsEntry::TitleWasSet(
ForEachTask(base::BindRepeating([](RendererTask* task) { content::NavigationEntry* entry) {
for (auto& it : site_instance_infos_) {
RendererTask* task = it.second.renderer_task.get();
task->UpdateTitle(); task->UpdateTitle();
task->UpdateFavicon(); task->UpdateFavicon();
})); }
} }
void WebContentsEntry::CreateTaskForFrame(RenderFrameHost* render_frame_host) { void WebContentsTaskProvider::WebContentsEntry::CreateTaskForFrame(
RenderFrameHost* render_frame_host) {
// Currently we do not track pending hosts, or pending delete hosts. // Currently we do not track pending hosts, or pending delete hosts.
DCHECK(render_frame_host->IsCurrent());
DCHECK(render_frame_host); DCHECK(render_frame_host);
DCHECK(!tasks_by_frames_.count(render_frame_host)); DCHECK(render_frame_host->IsCurrent());
content::SiteInstance* site_instance = render_frame_host->GetSiteInstance();
// Exclude sad tabs and sad oopifs. // Exclude sad tabs and sad OOPIFs.
if (!render_frame_host->IsRenderFrameLive()) if (!render_frame_host->IsRenderFrameLive())
return; return;
// Exclude frames in the same SiteInstance as their parent; |tasks_by_frames_| // Exclude frames in the same SiteInstance as their parent;
// only contains local roots. // |site_instance_by_frames_| only contains local roots.
content::SiteInstance* site_instance = render_frame_host->GetSiteInstance();
if (render_frame_host->GetParent() && if (render_frame_host->GetParent() &&
site_instance == render_frame_host->GetParent()->GetSiteInstance()) { site_instance == render_frame_host->GetParent()->GetSiteInstance()) {
return; return;
} }
bool site_instance_exists = bool site_instance_exists = site_instance_infos_.count(site_instance) != 0;
frames_by_site_instance_.count(site_instance) != 0;
bool is_main_frame = (render_frame_host == web_contents()->GetMainFrame()); bool is_main_frame = (render_frame_host == web_contents()->GetMainFrame());
bool site_instance_is_main = (site_instance == main_frame_site_instance_); bool site_instance_is_main = (site_instance == main_frame_site_instance_);
RendererTask* new_task = nullptr; std::unique_ptr<RendererTask> new_task;
// We need to create a task if one doesn't already exist for this // We need to create a task if one doesn't already exist for this
// SiteInstance, or if the main frame navigates to a process that currently is // SiteInstance, or if the main frame navigates to a process that currently is
...@@ -297,42 +301,29 @@ void WebContentsEntry::CreateTaskForFrame(RenderFrameHost* render_frame_host) { ...@@ -297,42 +301,29 @@ void WebContentsEntry::CreateTaskForFrame(RenderFrameHost* render_frame_host) {
new_task = tag->CreateTask(provider_); new_task = tag->CreateTask(provider_);
main_frame_site_instance_ = site_instance; main_frame_site_instance_ = site_instance;
} else { } else {
new_task = new_task = std::make_unique<SubframeTask>(
new SubframeTask(render_frame_host, web_contents(), render_frame_host, web_contents(),
GetTaskForFrame(web_contents()->GetMainFrame())); GetTaskForFrame(web_contents()->GetMainFrame()));
} }
} }
if (site_instance_exists) { auto insert_result =
// One of the existing frame hosts for this site instance. site_instance_infos_[site_instance].frames.insert(render_frame_host);
FramesList& existing_frames_for_site_instance = DCHECK(insert_result.second);
frames_by_site_instance_[site_instance];
RenderFrameHost* existing_rfh = existing_frames_for_site_instance[0];
RendererTask* old_task = tasks_by_frames_[existing_rfh];
if (!new_task) {
// We didn't create any new task, so we keep using the old one.
tasks_by_frames_[render_frame_host] = old_task;
} else {
// Overwrite all the existing old tasks with the new one, and delete the
// old one.
for (RenderFrameHost* frame : existing_frames_for_site_instance)
tasks_by_frames_[frame] = new_task;
provider_->NotifyObserverTaskRemoved(old_task); if (new_task) {
delete old_task; if (site_instance_exists) {
provider_->NotifyObserverTaskRemoved(
site_instance_infos_[site_instance].renderer_task.get());
} }
}
frames_by_site_instance_[site_instance].push_back(render_frame_host); RendererTask* new_task_ptr = new_task.get();
site_instance_infos_[site_instance].renderer_task = std::move(new_task);
if (new_task) { provider_->NotifyObserverTaskAdded(new_task_ptr);
tasks_by_frames_[render_frame_host] = new_task;
provider_->NotifyObserverTaskAdded(new_task);
// If we don't know the OS process handle yet (e.g., because this task is // If we don't know the OS process handle yet (e.g., because this task is
// still launching), update the task when it becomes available. // still launching), update the task when it becomes available.
if (new_task->process_id() == base::kNullProcessId) { if (new_task_ptr->process_id() == base::kNullProcessId) {
render_frame_host->GetProcess()->PostTaskWhenProcessIsReady( render_frame_host->GetProcess()->PostTaskWhenProcessIsReady(
base::BindOnce(&WebContentsEntry::RenderFrameReady, base::BindOnce(&WebContentsEntry::RenderFrameReady,
weak_factory_.GetWeakPtr(), weak_factory_.GetWeakPtr(),
...@@ -342,37 +333,43 @@ void WebContentsEntry::CreateTaskForFrame(RenderFrameHost* render_frame_host) { ...@@ -342,37 +333,43 @@ void WebContentsEntry::CreateTaskForFrame(RenderFrameHost* render_frame_host) {
} }
} }
void WebContentsEntry::ClearTaskForFrame(RenderFrameHost* render_frame_host) { void WebContentsTaskProvider::WebContentsEntry::ClearTaskForFrame(
auto itr = tasks_by_frames_.find(render_frame_host); RenderFrameHost* render_frame_host) {
if (itr == tasks_by_frames_.end()) DCHECK(render_frame_host);
content::SiteInstance* site_instance = render_frame_host->GetSiteInstance();
auto itr = site_instance_infos_.find(site_instance);
if (itr == site_instance_infos_.end())
return; return;
RendererTask* task = itr->second; auto& frames = itr->second.frames;
tasks_by_frames_.erase(itr); size_t count = frames.erase(render_frame_host);
content::SiteInstance* site_instance = render_frame_host->GetSiteInstance(); if (!count)
FramesList& frames = frames_by_site_instance_[site_instance]; return;
frames.erase(std::find(frames.begin(), frames.end(), render_frame_host));
if (frames.empty()) { if (frames.empty()) {
frames_by_site_instance_.erase(site_instance); std::unique_ptr<RendererTask> renderer_task =
provider_->NotifyObserverTaskRemoved(task); std::move(itr->second.renderer_task);
delete task; site_instance_infos_.erase(itr);
provider_->NotifyObserverTaskRemoved(renderer_task.get());
if (site_instance == main_frame_site_instance_) if (site_instance == main_frame_site_instance_)
main_frame_site_instance_ = nullptr; main_frame_site_instance_ = nullptr;
} }
// Whenever we have a task, we should have a main frame site instance. // Whenever we have a task, we should have a main frame site instance.
DCHECK(tasks_by_frames_.empty() == (main_frame_site_instance_ == nullptr)); DCHECK(site_instance_infos_.empty() ==
(main_frame_site_instance_ == nullptr));
} }
void WebContentsEntry::ClearTasksForDescendantsOf(RenderFrameHost* ancestor) { void WebContentsTaskProvider::WebContentsEntry::ClearTasksForDescendantsOf(
RenderFrameHost* ancestor) {
// 1) Collect descendants. // 1) Collect descendants.
std::vector<RenderFrameHost*> descendants; base::flat_set<RenderFrameHost*> descendants;
for (auto it : tasks_by_frames_) { for (const auto& site_instance_pair : site_instance_infos_) {
RenderFrameHost* frame = it.first; for (auto* frame : site_instance_pair.second.frames) {
if (frame->IsDescendantOf(ancestor)) if (frame->IsDescendantOf(ancestor))
descendants.push_back(frame); descendants.insert(frame);
}
} }
// 2) Delete them. // 2) Delete them.
...@@ -380,20 +377,9 @@ void WebContentsEntry::ClearTasksForDescendantsOf(RenderFrameHost* ancestor) { ...@@ -380,20 +377,9 @@ void WebContentsEntry::ClearTasksForDescendantsOf(RenderFrameHost* ancestor) {
ClearTaskForFrame(rfh); ClearTaskForFrame(rfh);
} }
void WebContentsEntry::ForEachTask(
base::RepeatingCallback<void(RendererTask*)> on_task) {
for (const auto& pair : frames_by_site_instance_) {
const FramesList& frames_list = pair.second;
DCHECK(!frames_list.empty());
RendererTask* task = tasks_by_frames_[frames_list[0]];
on_task.Run(task);
}
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
WebContentsTaskProvider::WebContentsTaskProvider() : is_updating_(false) {} WebContentsTaskProvider::WebContentsTaskProvider() = default;
WebContentsTaskProvider::~WebContentsTaskProvider() { WebContentsTaskProvider::~WebContentsTaskProvider() {
if (is_updating_) { if (is_updating_) {
...@@ -418,7 +404,7 @@ void WebContentsTaskProvider::OnWebContentsTagCreated( ...@@ -418,7 +404,7 @@ void WebContentsTaskProvider::OnWebContentsTagCreated(
return; return;
} }
entry.reset(new WebContentsEntry(web_contents, this)); entry = std::make_unique<WebContentsEntry>(web_contents, this);
entry->CreateAllTasks(); entry->CreateAllTasks();
} }
......
...@@ -17,7 +17,6 @@ class WebContents; ...@@ -17,7 +17,6 @@ class WebContents;
namespace task_manager { namespace task_manager {
class WebContentsEntry;
class WebContentsTag; class WebContentsTag;
// Defines a provider to provide the renderer tasks that are associated with // Defines a provider to provide the renderer tasks that are associated with
...@@ -45,7 +44,7 @@ class WebContentsTaskProvider : public TaskProvider { ...@@ -45,7 +44,7 @@ class WebContentsTaskProvider : public TaskProvider {
Task* GetTaskOfFrame(content::RenderFrameHost* frame); Task* GetTaskOfFrame(content::RenderFrameHost* frame);
private: private:
friend class WebContentsEntry; class WebContentsEntry;
// task_manager::TaskProvider: // task_manager::TaskProvider:
void StartUpdating() override; void StartUpdating() override;
...@@ -62,7 +61,7 @@ class WebContentsTaskProvider : public TaskProvider { ...@@ -62,7 +61,7 @@ class WebContentsTaskProvider : public TaskProvider {
// True if this provider is listening to WebContentsTags and updating its // True if this provider is listening to WebContentsTags and updating its
// observers, false otherwise. // observers, false otherwise.
bool is_updating_; bool is_updating_ = false;
DISALLOW_COPY_AND_ASSIGN(WebContentsTaskProvider); DISALLOW_COPY_AND_ASSIGN(WebContentsTaskProvider);
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment