| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/task_manager/providers/web_contents/web_contents_task_p
rovider.h" | 5 #include "chrome/browser/task_manager/providers/web_contents/web_contents_task_p
rovider.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/macros.h" | 8 #include "base/macros.h" |
| 9 #include "chrome/browser/task_manager/providers/web_contents/subframe_task.h" | 9 #include "chrome/browser/task_manager/providers/web_contents/subframe_task.h" |
| 10 #include "chrome/browser/task_manager/providers/web_contents/web_contents_tags_m
anager.h" | 10 #include "chrome/browser/task_manager/providers/web_contents/web_contents_tags_m
anager.h" |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 61 private: | 61 private: |
| 62 // Defines a callback for WebContents::ForEachFrame() to create a | 62 // Defines a callback for WebContents::ForEachFrame() to create a |
| 63 // corresponding task for the given |render_frame_host| and notifying the | 63 // corresponding task for the given |render_frame_host| and notifying the |
| 64 // provider's observer of the new task. | 64 // provider's observer of the new task. |
| 65 void CreateTaskForFrame(RenderFrameHost* render_frame_host); | 65 void CreateTaskForFrame(RenderFrameHost* render_frame_host); |
| 66 | 66 |
| 67 // Clears the task that corresponds to the given |render_frame_host| and | 67 // Clears the task that corresponds to the given |render_frame_host| and |
| 68 // notifies the provider's observer of the tasks removal. | 68 // notifies the provider's observer of the tasks removal. |
| 69 void ClearTaskForFrame(RenderFrameHost* render_frame_host); | 69 void ClearTaskForFrame(RenderFrameHost* render_frame_host); |
| 70 | 70 |
| 71 // Calls |on_task| for each task managed by this WebContentsEntry. |
| 72 void ForEachTask(const base::Callback<void(RendererTask*)>& on_task); |
| 73 |
| 71 // The provider that owns this entry. | 74 // The provider that owns this entry. |
| 72 WebContentsTaskProvider* provider_; | 75 WebContentsTaskProvider* provider_; |
| 73 | 76 |
| 74 // The RenderFrameHosts associated with this entry's WebContents that we're | 77 // The RenderFrameHosts associated with this entry's WebContents that we're |
| 75 // tracking mapped by their SiteInstances. | 78 // tracking mapped by their SiteInstances. |
| 76 using FramesList = std::vector<RenderFrameHost*>; | 79 using FramesList = std::vector<RenderFrameHost*>; |
| 77 using SiteInstanceToFramesMap = std::map<SiteInstance*, FramesList>; | 80 std::map<SiteInstance*, FramesList> frames_by_site_instance_; |
| 78 SiteInstanceToFramesMap frames_by_site_instance_; | |
| 79 | 81 |
| 80 // The RendererTasks that we create for the task manager, mapped by their | 82 // The RendererTasks that we create for the task manager, mapped by their |
| 81 // RenderFrameHosts. | 83 // RenderFrameHosts. This owns the RenderTasks. |
| 82 using FramesToTasksMap = std::map<RenderFrameHost*, RendererTask*>; | 84 std::map<RenderFrameHost*, RendererTask*> tasks_by_frames_; |
| 83 FramesToTasksMap tasks_by_frames_; | |
| 84 | 85 |
| 85 // States whether we did record a main frame for this entry. | 86 // States whether we did record a main frame for this entry. |
| 86 SiteInstance* main_frame_site_instance_; | 87 SiteInstance* main_frame_site_instance_; |
| 87 | 88 |
| 88 DISALLOW_COPY_AND_ASSIGN(WebContentsEntry); | 89 DISALLOW_COPY_AND_ASSIGN(WebContentsEntry); |
| 89 }; | 90 }; |
| 90 | 91 |
| 91 //////////////////////////////////////////////////////////////////////////////// | 92 //////////////////////////////////////////////////////////////////////////////// |
| 92 | 93 |
| 93 WebContentsEntry::WebContentsEntry(content::WebContents* web_contents, | 94 WebContentsEntry::WebContentsEntry(content::WebContents* web_contents, |
| 94 WebContentsTaskProvider* provider) | 95 WebContentsTaskProvider* provider) |
| 95 : WebContentsObserver(web_contents), | 96 : WebContentsObserver(web_contents), |
| 96 provider_(provider), | 97 provider_(provider), |
| 97 main_frame_site_instance_(nullptr) { | 98 main_frame_site_instance_(nullptr) { |
| 98 } | 99 } |
| 99 | 100 |
| 100 WebContentsEntry::~WebContentsEntry() { | 101 WebContentsEntry::~WebContentsEntry() { |
| 101 ClearAllTasks(false); | 102 ClearAllTasks(false); |
| 102 } | 103 } |
| 103 | 104 |
| 104 void WebContentsEntry::CreateAllTasks() { | 105 void WebContentsEntry::CreateAllTasks() { |
| 105 DCHECK(web_contents()->GetMainFrame()); | 106 DCHECK(web_contents()->GetMainFrame()); |
| 106 web_contents()->ForEachFrame(base::Bind(&WebContentsEntry::CreateTaskForFrame, | 107 web_contents()->ForEachFrame(base::Bind(&WebContentsEntry::CreateTaskForFrame, |
| 107 base::Unretained(this))); | 108 base::Unretained(this))); |
| 108 } | 109 } |
| 109 | 110 |
| 110 void WebContentsEntry::ClearAllTasks(bool notify_observer) { | 111 void WebContentsEntry::ClearAllTasks(bool notify_observer) { |
| 111 for (const auto& pair : frames_by_site_instance_) { | 112 ForEachTask(base::Bind( |
| 112 const FramesList& frames_list = pair.second; | 113 [](WebContentsTaskProvider* provider, bool notify_observer, |
| 113 DCHECK(!frames_list.empty()); | 114 content::WebContents* web_contents, RendererTask* task) { |
| 114 RendererTask* task = tasks_by_frames_[frames_list[0]]; | 115 task->set_termination_status(web_contents->GetCrashedStatus()); |
| 116 task->set_termination_error_code(web_contents->GetCrashedErrorCode()); |
| 115 | 117 |
| 116 task->set_termination_status(web_contents()->GetCrashedStatus()); | 118 if (notify_observer) |
| 117 task->set_termination_error_code(web_contents()->GetCrashedErrorCode()); | 119 provider->NotifyObserverTaskRemoved(task); |
| 118 | 120 delete task; |
| 119 if (notify_observer) | 121 }, |
| 120 provider_->NotifyObserverTaskRemoved(task); | 122 provider_, notify_observer, web_contents())); |
| 121 delete task; | |
| 122 } | |
| 123 | 123 |
| 124 frames_by_site_instance_.clear(); | 124 frames_by_site_instance_.clear(); |
| 125 tasks_by_frames_.clear(); | 125 tasks_by_frames_.clear(); |
| 126 main_frame_site_instance_ = nullptr; | 126 main_frame_site_instance_ = nullptr; |
| 127 } | 127 } |
| 128 | 128 |
| 129 RendererTask* WebContentsEntry::GetTaskForFrame( | 129 RendererTask* WebContentsEntry::GetTaskForFrame( |
| 130 RenderFrameHost* render_frame_host) const { | 130 RenderFrameHost* render_frame_host) const { |
| 131 auto itr = tasks_by_frames_.find(render_frame_host); | 131 auto itr = tasks_by_frames_.find(render_frame_host); |
| 132 if (itr == tasks_by_frames_.end()) | 132 if (itr == tasks_by_frames_.end()) |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 166 return; | 166 return; |
| 167 | 167 |
| 168 DCHECK_EQ(render_widget_host->GetProcess(), | 168 DCHECK_EQ(render_widget_host->GetProcess(), |
| 169 web_contents()->GetMainFrame()->GetProcess()); | 169 web_contents()->GetMainFrame()->GetProcess()); |
| 170 | 170 |
| 171 provider_->NotifyObserverTaskUnresponsive(task); | 171 provider_->NotifyObserverTaskUnresponsive(task); |
| 172 } | 172 } |
| 173 | 173 |
| 174 void WebContentsEntry::DidFinishNavigation( | 174 void WebContentsEntry::DidFinishNavigation( |
| 175 content::NavigationHandle* navigation_handle) { | 175 content::NavigationHandle* navigation_handle) { |
| 176 RendererTask* task = GetTaskForFrame(web_contents()->GetMainFrame()); | 176 RendererTask* main_frame_task = |
| 177 if (!task) | 177 GetTaskForFrame(web_contents()->GetMainFrame()); |
| 178 if (!main_frame_task) |
| 178 return; | 179 return; |
| 179 | 180 |
| 180 // Listening to WebContentsObserver::TitleWasSet() only is not enough in | 181 main_frame_task->UpdateRapporSampleName(); |
| 181 // some cases when the the webpage doesn't have a title. That's why we update | |
| 182 // the title here as well. | |
| 183 task->UpdateTitle(); | |
| 184 | 182 |
| 185 // Call RendererTask::UpdateFavicon() to set the current favicon to the | 183 ForEachTask(base::Bind([](RendererTask* task) { |
| 186 // default favicon. If the page has a non-default favicon, | 184 // Listening to WebContentsObserver::TitleWasSet() only is not enough in |
| 187 // RendererTask::OnFaviconUpdated() will update the current favicon once | 185 // some cases when the the web page doesn't have a title. That's why we |
| 188 // FaviconDriver figures out the correct favicon for the page. | 186 // update the title here as well. |
| 189 task->UpdateFavicon(); | 187 task->UpdateTitle(); |
| 190 task->UpdateRapporSampleName(); | 188 |
| 189 // Call RendererTask::UpdateFavicon() to set the current favicon to the |
| 190 // default favicon. If the page has a non-default favicon, |
| 191 // RendererTask::OnFaviconUpdated() will update the current favicon once |
| 192 // FaviconDriver figures out the correct favicon for the page. |
| 193 task->UpdateFavicon(); |
| 194 })); |
| 191 } | 195 } |
| 192 | 196 |
| 193 void WebContentsEntry::TitleWasSet(content::NavigationEntry* entry, | 197 void WebContentsEntry::TitleWasSet(content::NavigationEntry* entry, |
| 194 bool explicit_set) { | 198 bool explicit_set) { |
| 195 RendererTask* task = GetTaskForFrame(web_contents()->GetMainFrame()); | 199 ForEachTask(base::Bind([](RendererTask* task) { |
| 196 if (!task) | 200 task->UpdateTitle(); |
| 197 return; | 201 task->UpdateFavicon(); |
| 198 | 202 })); |
| 199 task->UpdateTitle(); | |
| 200 task->UpdateFavicon(); | |
| 201 } | 203 } |
| 202 | 204 |
| 203 void WebContentsEntry::CreateTaskForFrame(RenderFrameHost* render_frame_host) { | 205 void WebContentsEntry::CreateTaskForFrame(RenderFrameHost* render_frame_host) { |
| 204 DCHECK(!tasks_by_frames_.count(render_frame_host)); | 206 DCHECK(!tasks_by_frames_.count(render_frame_host)); |
| 205 | 207 |
| 206 content::SiteInstance* site_instance = render_frame_host->GetSiteInstance(); | 208 content::SiteInstance* site_instance = render_frame_host->GetSiteInstance(); |
| 207 if (!site_instance->GetProcess()->HasConnection()) | 209 if (!site_instance->GetProcess()->HasConnection()) |
| 208 return; | 210 return; |
| 209 | 211 |
| 210 bool site_instance_exists = | 212 bool site_instance_exists = |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 271 if (frames.empty()) { | 273 if (frames.empty()) { |
| 272 frames_by_site_instance_.erase(site_instance); | 274 frames_by_site_instance_.erase(site_instance); |
| 273 provider_->NotifyObserverTaskRemoved(task); | 275 provider_->NotifyObserverTaskRemoved(task); |
| 274 delete task; | 276 delete task; |
| 275 | 277 |
| 276 if (site_instance == main_frame_site_instance_) | 278 if (site_instance == main_frame_site_instance_) |
| 277 main_frame_site_instance_ = nullptr; | 279 main_frame_site_instance_ = nullptr; |
| 278 } | 280 } |
| 279 } | 281 } |
| 280 | 282 |
| 283 void WebContentsEntry::ForEachTask( |
| 284 const base::Callback<void(RendererTask*)>& on_task) { |
| 285 for (const auto& pair : frames_by_site_instance_) { |
| 286 const FramesList& frames_list = pair.second; |
| 287 DCHECK(!frames_list.empty()); |
| 288 RendererTask* task = tasks_by_frames_[frames_list[0]]; |
| 289 |
| 290 on_task.Run(task); |
| 291 } |
| 292 } |
| 293 |
| 281 //////////////////////////////////////////////////////////////////////////////// | 294 //////////////////////////////////////////////////////////////////////////////// |
| 282 | 295 |
| 283 WebContentsTaskProvider::WebContentsTaskProvider() | 296 WebContentsTaskProvider::WebContentsTaskProvider() |
| 284 : is_updating_(false) { | 297 : is_updating_(false) { |
| 285 } | 298 } |
| 286 | 299 |
| 287 WebContentsTaskProvider::~WebContentsTaskProvider() { | 300 WebContentsTaskProvider::~WebContentsTaskProvider() { |
| 288 if (is_updating_) { | 301 if (is_updating_) { |
| 289 StopUpdating(); | 302 StopUpdating(); |
| 290 } | 303 } |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 376 } | 389 } |
| 377 | 390 |
| 378 void WebContentsTaskProvider::DeleteEntry(content::WebContents* web_contents) { | 391 void WebContentsTaskProvider::DeleteEntry(content::WebContents* web_contents) { |
| 379 // This erase() will delete the WebContentsEntry, which is actually our | 392 // This erase() will delete the WebContentsEntry, which is actually our |
| 380 // caller, but it's expecting us to delete it. | 393 // caller, but it's expecting us to delete it. |
| 381 bool success = entries_map_.erase(web_contents) != 0; | 394 bool success = entries_map_.erase(web_contents) != 0; |
| 382 DCHECK(success); | 395 DCHECK(success); |
| 383 } | 396 } |
| 384 | 397 |
| 385 } // namespace task_manager | 398 } // namespace task_manager |
| OLD | NEW |