| 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 "base/memory/weak_ptr.h" | 9 #include "base/memory/weak_ptr.h" |
| 10 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 48 // |render_frame_host| or |nullptr| if the given frame is not tracked by this | 48 // |render_frame_host| or |nullptr| if the given frame is not tracked by this |
| 49 // entry. | 49 // entry. |
| 50 RendererTask* GetTaskForFrame(RenderFrameHost* render_frame_host) const; | 50 RendererTask* GetTaskForFrame(RenderFrameHost* render_frame_host) const; |
| 51 | 51 |
| 52 // content::WebContentsObserver: | 52 // content::WebContentsObserver: |
| 53 void RenderFrameDeleted(RenderFrameHost* render_frame_host) override; | 53 void RenderFrameDeleted(RenderFrameHost* render_frame_host) override; |
| 54 void RenderFrameHostChanged(RenderFrameHost* old_host, | 54 void RenderFrameHostChanged(RenderFrameHost* old_host, |
| 55 RenderFrameHost* new_host) override; | 55 RenderFrameHost* new_host) override; |
| 56 void RenderFrameCreated(RenderFrameHost*) override; | 56 void RenderFrameCreated(RenderFrameHost*) override; |
| 57 void WebContentsDestroyed() override; | 57 void WebContentsDestroyed() override; |
| 58 void RenderProcessGone(base::TerminationStatus status) override; | |
| 59 void OnRendererUnresponsive(RenderWidgetHost* render_widget_host) override; | 58 void OnRendererUnresponsive(RenderWidgetHost* render_widget_host) override; |
| 60 void DidFinishNavigation( | 59 void DidFinishNavigation( |
| 61 content::NavigationHandle* navigation_handle) override; | 60 content::NavigationHandle* navigation_handle) override; |
| 62 void TitleWasSet(content::NavigationEntry* entry, bool explicit_set) override; | 61 void TitleWasSet(content::NavigationEntry* entry, bool explicit_set) override; |
| 63 | 62 |
| 64 void RenderFrameReady(int process_routing_id, int frame_routing_id); | 63 void RenderFrameReady(int process_routing_id, int frame_routing_id); |
| 65 | 64 |
| 66 private: | 65 private: |
| 67 // Defines a callback for WebContents::ForEachFrame() to create a | 66 // Defines a callback for WebContents::ForEachFrame() to create a |
| 68 // corresponding task for the given |render_frame_host| and notifying the | 67 // corresponding task for the given |render_frame_host| and notifying the |
| 69 // provider's observer of the new task. | 68 // provider's observer of the new task. |
| 70 void CreateTaskForFrame(RenderFrameHost* render_frame_host); | 69 void CreateTaskForFrame(RenderFrameHost* render_frame_host); |
| 71 | 70 |
| 72 // Clears the task that corresponds to the given |render_frame_host| and | 71 // Clears the task that corresponds to the given |render_frame_host| and |
| 73 // notifies the provider's observer of the tasks removal. | 72 // notifies the provider's observer of the tasks removal. |
| 74 void ClearTaskForFrame(RenderFrameHost* render_frame_host); | 73 void ClearTaskForFrame(RenderFrameHost* render_frame_host); |
| 75 | 74 |
| 76 // Calls |on_task| for each task managed by this WebContentsEntry. | 75 // Calls |on_task| for each task managed by this WebContentsEntry. |
| 77 void ForEachTask(const base::Callback<void(RendererTask*)>& on_task); | 76 void ForEachTask(const base::Callback<void(RendererTask*)>& on_task); |
| 78 | 77 |
| 78 // Walks parents until hitting a process boundary. Returns the highest frame |
| 79 // in the same SiteInstance as |render_frame_host|. |
| 80 RenderFrameHost* FindLocalRoot(RenderFrameHost* render_frame_host) const; |
| 81 |
| 79 // The provider that owns this entry. | 82 // The provider that owns this entry. |
| 80 WebContentsTaskProvider* provider_; | 83 WebContentsTaskProvider* provider_; |
| 81 | 84 |
| 82 // The RenderFrameHosts associated with this entry's WebContents that we're | 85 // The RenderFrameHosts associated with this entry's WebContents that we're |
| 83 // tracking mapped by their SiteInstances. | 86 // tracking mapped by their SiteInstances. |
| 84 using FramesList = std::vector<RenderFrameHost*>; | 87 using FramesList = std::vector<RenderFrameHost*>; |
| 85 std::map<SiteInstance*, FramesList> frames_by_site_instance_; | 88 std::map<SiteInstance*, FramesList> frames_by_site_instance_; |
| 86 | 89 |
| 87 // The RendererTasks that we create for the task manager, mapped by their | 90 // The RendererTasks that we create for the task manager, mapped by their |
| 88 // RenderFrameHosts. This owns the RenderTasks. | 91 // RenderFrameHosts. This owns the RenderTasks. |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 128 }, | 131 }, |
| 129 provider_, notify_observer, web_contents())); | 132 provider_, notify_observer, web_contents())); |
| 130 | 133 |
| 131 frames_by_site_instance_.clear(); | 134 frames_by_site_instance_.clear(); |
| 132 tasks_by_frames_.clear(); | 135 tasks_by_frames_.clear(); |
| 133 main_frame_site_instance_ = nullptr; | 136 main_frame_site_instance_ = nullptr; |
| 134 } | 137 } |
| 135 | 138 |
| 136 RendererTask* WebContentsEntry::GetTaskForFrame( | 139 RendererTask* WebContentsEntry::GetTaskForFrame( |
| 137 RenderFrameHost* render_frame_host) const { | 140 RenderFrameHost* render_frame_host) const { |
| 138 auto itr = tasks_by_frames_.find(render_frame_host); | 141 // Only local roots are in |tasks_by_frames_|. |
| 142 auto itr = tasks_by_frames_.find(FindLocalRoot(render_frame_host)); |
| 139 if (itr == tasks_by_frames_.end()) | 143 if (itr == tasks_by_frames_.end()) |
| 140 return nullptr; | 144 return nullptr; |
| 141 | 145 |
| 142 return itr->second; | 146 return itr->second; |
| 143 } | 147 } |
| 144 | 148 |
| 149 RenderFrameHost* WebContentsEntry::FindLocalRoot( |
| 150 RenderFrameHost* render_frame_host) const { |
| 151 SiteInstance* site_instance = render_frame_host->GetSiteInstance(); |
| 152 RenderFrameHost* candidate = render_frame_host; |
| 153 while (RenderFrameHost* parent = candidate->GetParent()) { |
| 154 if (parent->GetSiteInstance() != site_instance) |
| 155 break; |
| 156 candidate = parent; |
| 157 } |
| 158 return candidate; |
| 159 } |
| 160 |
| 145 void WebContentsEntry::RenderFrameDeleted(RenderFrameHost* render_frame_host) { | 161 void WebContentsEntry::RenderFrameDeleted(RenderFrameHost* render_frame_host) { |
| 146 ClearTaskForFrame(render_frame_host); | 162 ClearTaskForFrame(render_frame_host); |
| 147 } | 163 } |
| 148 | 164 |
| 149 void WebContentsEntry::RenderFrameHostChanged(RenderFrameHost* old_host, | 165 void WebContentsEntry::RenderFrameHostChanged(RenderFrameHost* old_host, |
| 150 RenderFrameHost* new_host) { | 166 RenderFrameHost* new_host) { |
| 167 DCHECK(new_host->IsCurrent()); |
| 151 ClearTaskForFrame(old_host); | 168 ClearTaskForFrame(old_host); |
| 152 CreateTaskForFrame(new_host); | 169 CreateTaskForFrame(new_host); |
| 153 } | 170 } |
| 154 | 171 |
| 155 void WebContentsEntry::RenderFrameCreated(RenderFrameHost* render_frame_host) { | 172 void WebContentsEntry::RenderFrameCreated(RenderFrameHost* render_frame_host) { |
| 173 DCHECK(render_frame_host->IsRenderFrameLive()); |
| 174 |
| 156 // Skip pending/speculative hosts. We'll create tasks for these if the | 175 // Skip pending/speculative hosts. We'll create tasks for these if the |
| 157 // navigation commits, at which point RenderFrameHostChanged() will fire. | 176 // navigation commits, at which point RenderFrameHostChanged() will fire. |
| 158 if (!render_frame_host->IsCurrent()) | 177 if (!render_frame_host->IsCurrent()) |
| 159 return; | 178 return; |
| 160 | 179 |
| 161 // Task manager will have no separate entry for |render_frame_host| if it has | 180 CreateTaskForFrame(render_frame_host); |
| 162 // the same site instance as its parent - quit early in this case. | |
| 163 if (render_frame_host->GetParent() && | |
| 164 render_frame_host->GetParent()->GetSiteInstance() == | |
| 165 render_frame_host->GetSiteInstance()) | |
| 166 return; | |
| 167 | |
| 168 // Postpone processing |render_frame_host| until its process has a PID. | |
| 169 render_frame_host->GetProcess()->PostTaskWhenProcessIsReady(base::Bind( | |
| 170 &WebContentsEntry::RenderFrameReady, weak_factory_.GetWeakPtr(), | |
| 171 render_frame_host->GetProcess()->GetID(), | |
| 172 render_frame_host->GetRoutingID())); | |
| 173 } | 181 } |
| 174 | 182 |
| 175 void WebContentsEntry::RenderFrameReady(int render_process_id, | 183 void WebContentsEntry::RenderFrameReady(int render_process_id, |
| 176 int render_frame_id) { | 184 int render_frame_id) { |
| 185 // We get here when a RenderProcessHost we are tracking transitions to the |
| 186 // IsReady state. This might mean we know its process ID. |
| 177 content::RenderFrameHost* render_frame_host = | 187 content::RenderFrameHost* render_frame_host = |
| 178 content::RenderFrameHost::FromID(render_process_id, render_frame_id); | 188 content::RenderFrameHost::FromID(render_process_id, render_frame_id); |
| 179 if (render_frame_host) | 189 if (!render_frame_host) |
| 180 CreateTaskForFrame(render_frame_host); | 190 return; |
| 191 |
| 192 Task* task = GetTaskForFrame(render_frame_host); |
| 193 |
| 194 if (!task) |
| 195 return; |
| 196 |
| 197 const base::ProcessId determine_pid_from_handle = base::kNullProcessId; |
| 198 provider_->UpdateTaskProcessInfoAndNotifyObserver( |
| 199 task, render_frame_host->GetProcess()->GetHandle(), |
| 200 determine_pid_from_handle); |
| 181 } | 201 } |
| 182 | 202 |
| 183 void WebContentsEntry::WebContentsDestroyed() { | 203 void WebContentsEntry::WebContentsDestroyed() { |
| 184 ClearAllTasks(true); | 204 ClearAllTasks(true); |
| 185 provider_->DeleteEntry(web_contents()); | 205 provider_->DeleteEntry(web_contents()); |
| 186 } | 206 } |
| 187 | 207 |
| 188 void WebContentsEntry::RenderProcessGone(base::TerminationStatus status) { | |
| 189 ClearAllTasks(true); | |
| 190 } | |
| 191 | |
| 192 void WebContentsEntry::OnRendererUnresponsive( | 208 void WebContentsEntry::OnRendererUnresponsive( |
| 193 RenderWidgetHost* render_widget_host) { | 209 RenderWidgetHost* render_widget_host) { |
| 194 // Find the first RenderFrameHost matching the RenderWidgetHost. | 210 // Find the first RenderFrameHost matching the RenderWidgetHost. |
| 195 RendererTask* task = nullptr; | 211 RendererTask* task = nullptr; |
| 196 for (const auto& pair : tasks_by_frames_) { | 212 for (const auto& pair : tasks_by_frames_) { |
| 197 if (pair.first->GetView() == render_widget_host->GetView()) { | 213 if (pair.first->GetView() == render_widget_host->GetView()) { |
| 198 DCHECK_EQ(pair.first->GetProcess(), render_widget_host->GetProcess()); | 214 DCHECK_EQ(pair.first->GetProcess(), render_widget_host->GetProcess()); |
| 199 task = pair.second; | 215 task = pair.second; |
| 200 break; | 216 break; |
| 201 } | 217 } |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 235 | 251 |
| 236 void WebContentsEntry::TitleWasSet(content::NavigationEntry* entry, | 252 void WebContentsEntry::TitleWasSet(content::NavigationEntry* entry, |
| 237 bool explicit_set) { | 253 bool explicit_set) { |
| 238 ForEachTask(base::Bind([](RendererTask* task) { | 254 ForEachTask(base::Bind([](RendererTask* task) { |
| 239 task->UpdateTitle(); | 255 task->UpdateTitle(); |
| 240 task->UpdateFavicon(); | 256 task->UpdateFavicon(); |
| 241 })); | 257 })); |
| 242 } | 258 } |
| 243 | 259 |
| 244 void WebContentsEntry::CreateTaskForFrame(RenderFrameHost* render_frame_host) { | 260 void WebContentsEntry::CreateTaskForFrame(RenderFrameHost* render_frame_host) { |
| 261 // Currently we do not track pending hosts, or pending delete hosts. |
| 262 DCHECK(render_frame_host->IsCurrent()); |
| 245 DCHECK(render_frame_host); | 263 DCHECK(render_frame_host); |
| 246 DCHECK(!tasks_by_frames_.count(render_frame_host)); | 264 DCHECK(!tasks_by_frames_.count(render_frame_host)); |
| 247 | 265 |
| 248 content::SiteInstance* site_instance = render_frame_host->GetSiteInstance(); | 266 content::SiteInstance* site_instance = render_frame_host->GetSiteInstance(); |
| 249 if (!site_instance->GetProcess()->HasConnection()) | 267 |
| 250 return; | 268 // Exclude sad tabs and sad oopifs. |
| 251 if (!render_frame_host->IsRenderFrameLive()) | 269 if (!render_frame_host->IsRenderFrameLive()) |
| 252 return; | 270 return; |
| 253 | 271 |
| 272 // Exclude frames in the same SiteInstance as their parent; |tasks_by_frames_| |
| 273 // only contains local roots. |
| 274 if (render_frame_host->GetParent() && |
| 275 site_instance == render_frame_host->GetParent()->GetSiteInstance()) { |
| 276 return; |
| 277 } |
| 278 |
| 254 bool site_instance_exists = | 279 bool site_instance_exists = |
| 255 frames_by_site_instance_.count(site_instance) != 0; | 280 frames_by_site_instance_.count(site_instance) != 0; |
| 256 bool is_main_frame = (render_frame_host == web_contents()->GetMainFrame()); | 281 bool is_main_frame = (render_frame_host == web_contents()->GetMainFrame()); |
| 257 bool site_instance_is_main = (site_instance == main_frame_site_instance_); | 282 bool site_instance_is_main = (site_instance == main_frame_site_instance_); |
| 258 | 283 |
| 259 RendererTask* new_task = nullptr; | 284 RendererTask* new_task = nullptr; |
| 260 // We don't create a task if there's one for this site_instance AND | 285 |
| 261 // if this is not the main frame or we did record a main frame for the entry. | 286 // We need to create a task if one doesn't already exist for this |
| 287 // SiteInstance, or if the main frame navigates to a process that currently is |
| 288 // represented by a SubframeTask. |
| 262 if (!site_instance_exists || (is_main_frame && !site_instance_is_main)) { | 289 if (!site_instance_exists || (is_main_frame && !site_instance_is_main)) { |
| 263 if (is_main_frame) { | 290 if (is_main_frame) { |
| 264 const WebContentsTag* tag = | 291 const WebContentsTag* tag = |
| 265 WebContentsTag::FromWebContents(web_contents()); | 292 WebContentsTag::FromWebContents(web_contents()); |
| 266 new_task = tag->CreateTask(); | 293 new_task = tag->CreateTask(); |
| 267 main_frame_site_instance_ = site_instance; | 294 main_frame_site_instance_ = site_instance; |
| 268 } else { | 295 } else { |
| 269 new_task = | 296 new_task = |
| 270 new SubframeTask(render_frame_host, web_contents(), | 297 new SubframeTask(render_frame_host, web_contents(), |
| 271 GetTaskForFrame(web_contents()->GetMainFrame())); | 298 GetTaskForFrame(web_contents()->GetMainFrame())); |
| 272 } | 299 } |
| 273 } | 300 } |
| 274 | 301 |
| 275 if (site_instance_exists) { | 302 if (site_instance_exists) { |
| 276 // One of the existing frame hosts for this site instance. | 303 // One of the existing frame hosts for this site instance. |
| 277 FramesList& existing_frames_for_site_instance = | 304 FramesList& existing_frames_for_site_instance = |
| 278 frames_by_site_instance_[site_instance]; | 305 frames_by_site_instance_[site_instance]; |
| 279 RenderFrameHost* existing_rfh = existing_frames_for_site_instance[0]; | 306 RenderFrameHost* existing_rfh = existing_frames_for_site_instance[0]; |
| 280 RendererTask* old_task = tasks_by_frames_[existing_rfh]; | 307 RendererTask* old_task = tasks_by_frames_[existing_rfh]; |
| 281 | 308 |
| 282 if (!new_task) { | 309 if (!new_task) { |
| 283 // We didn't create any new task, so we keep appending the old one. | 310 // We didn't create any new task, so we keep using the old one. |
| 284 tasks_by_frames_[render_frame_host] = old_task; | 311 tasks_by_frames_[render_frame_host] = old_task; |
| 285 } else { | 312 } else { |
| 286 // Overwrite all the existing old tasks with the new one, and delete the | 313 // Overwrite all the existing old tasks with the new one, and delete the |
| 287 // old one. | 314 // old one. |
| 288 for (RenderFrameHost* frame : existing_frames_for_site_instance) | 315 for (RenderFrameHost* frame : existing_frames_for_site_instance) |
| 289 tasks_by_frames_[frame] = new_task; | 316 tasks_by_frames_[frame] = new_task; |
| 290 | 317 |
| 291 provider_->NotifyObserverTaskRemoved(old_task); | 318 provider_->NotifyObserverTaskRemoved(old_task); |
| 292 delete old_task; | 319 delete old_task; |
| 293 } | 320 } |
| 294 } | 321 } |
| 295 | 322 |
| 296 frames_by_site_instance_[site_instance].push_back(render_frame_host); | 323 frames_by_site_instance_[site_instance].push_back(render_frame_host); |
| 297 | 324 |
| 298 if (new_task) { | 325 if (new_task) { |
| 299 tasks_by_frames_[render_frame_host] = new_task; | 326 tasks_by_frames_[render_frame_host] = new_task; |
| 300 provider_->NotifyObserverTaskAdded(new_task); | 327 provider_->NotifyObserverTaskAdded(new_task); |
| 328 |
| 329 // If we don't know the OS process handle yet (e.g., because this task is |
| 330 // still launching), update the task when it becomes available. |
| 331 if (new_task->process_id() == base::kNullProcessId) { |
| 332 render_frame_host->GetProcess()->PostTaskWhenProcessIsReady(base::Bind( |
| 333 &WebContentsEntry::RenderFrameReady, weak_factory_.GetWeakPtr(), |
| 334 render_frame_host->GetProcess()->GetID(), |
| 335 render_frame_host->GetRoutingID())); |
| 336 } |
| 301 } | 337 } |
| 302 } | 338 } |
| 303 | 339 |
| 304 void WebContentsEntry::ClearTaskForFrame(RenderFrameHost* render_frame_host) { | 340 void WebContentsEntry::ClearTaskForFrame(RenderFrameHost* render_frame_host) { |
| 305 auto itr = tasks_by_frames_.find(render_frame_host); | 341 auto itr = tasks_by_frames_.find(render_frame_host); |
| 306 if (itr == tasks_by_frames_.end()) | 342 if (itr == tasks_by_frames_.end()) |
| 307 return; | 343 return; |
| 308 | 344 |
| 309 RendererTask* task = itr->second; | 345 RendererTask* task = itr->second; |
| 310 tasks_by_frames_.erase(itr); | 346 tasks_by_frames_.erase(itr); |
| 311 content::SiteInstance* site_instance = render_frame_host->GetSiteInstance(); | 347 content::SiteInstance* site_instance = render_frame_host->GetSiteInstance(); |
| 312 FramesList& frames = frames_by_site_instance_[site_instance]; | 348 FramesList& frames = frames_by_site_instance_[site_instance]; |
| 313 frames.erase(std::find(frames.begin(), frames.end(), render_frame_host)); | 349 frames.erase(std::find(frames.begin(), frames.end(), render_frame_host)); |
| 314 | 350 |
| 315 if (frames.empty()) { | 351 if (frames.empty()) { |
| 316 frames_by_site_instance_.erase(site_instance); | 352 frames_by_site_instance_.erase(site_instance); |
| 317 provider_->NotifyObserverTaskRemoved(task); | 353 provider_->NotifyObserverTaskRemoved(task); |
| 318 delete task; | 354 delete task; |
| 319 | 355 |
| 320 if (site_instance == main_frame_site_instance_) | 356 if (site_instance == main_frame_site_instance_) |
| 321 main_frame_site_instance_ = nullptr; | 357 main_frame_site_instance_ = nullptr; |
| 322 } | 358 } |
| 359 |
| 360 // Whenever we have a task, we should have a main frame site instance. |
| 361 DCHECK(tasks_by_frames_.empty() == (main_frame_site_instance_ == nullptr)); |
| 323 } | 362 } |
| 324 | 363 |
| 325 void WebContentsEntry::ForEachTask( | 364 void WebContentsEntry::ForEachTask( |
| 326 const base::Callback<void(RendererTask*)>& on_task) { | 365 const base::Callback<void(RendererTask*)>& on_task) { |
| 327 for (const auto& pair : frames_by_site_instance_) { | 366 for (const auto& pair : frames_by_site_instance_) { |
| 328 const FramesList& frames_list = pair.second; | 367 const FramesList& frames_list = pair.second; |
| 329 DCHECK(!frames_list.empty()); | 368 DCHECK(!frames_list.empty()); |
| 330 RendererTask* task = tasks_by_frames_[frames_list[0]]; | 369 RendererTask* task = tasks_by_frames_[frames_list[0]]; |
| 331 | 370 |
| 332 on_task.Run(task); | 371 on_task.Run(task); |
| 333 } | 372 } |
| 334 } | 373 } |
| 335 | 374 |
| 336 //////////////////////////////////////////////////////////////////////////////// | 375 //////////////////////////////////////////////////////////////////////////////// |
| 337 | 376 |
| 338 WebContentsTaskProvider::WebContentsTaskProvider() | 377 WebContentsTaskProvider::WebContentsTaskProvider() : is_updating_(false) {} |
| 339 : is_updating_(false) { | |
| 340 } | |
| 341 | 378 |
| 342 WebContentsTaskProvider::~WebContentsTaskProvider() { | 379 WebContentsTaskProvider::~WebContentsTaskProvider() { |
| 343 if (is_updating_) { | 380 if (is_updating_) { |
| 344 StopUpdating(); | 381 StopUpdating(); |
| 345 } | 382 } |
| 346 } | 383 } |
| 347 | 384 |
| 348 void WebContentsTaskProvider::OnWebContentsTagCreated( | 385 void WebContentsTaskProvider::OnWebContentsTagCreated( |
| 349 const WebContentsTag* tag) { | 386 const WebContentsTag* tag) { |
| 350 DCHECK(tag); | 387 DCHECK(tag); |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 431 } | 468 } |
| 432 | 469 |
| 433 void WebContentsTaskProvider::DeleteEntry(content::WebContents* web_contents) { | 470 void WebContentsTaskProvider::DeleteEntry(content::WebContents* web_contents) { |
| 434 // This erase() will delete the WebContentsEntry, which is actually our | 471 // This erase() will delete the WebContentsEntry, which is actually our |
| 435 // caller, but it's expecting us to delete it. | 472 // caller, but it's expecting us to delete it. |
| 436 bool success = entries_map_.erase(web_contents) != 0; | 473 bool success = entries_map_.erase(web_contents) != 0; |
| 437 DCHECK(success); | 474 DCHECK(success); |
| 438 } | 475 } |
| 439 | 476 |
| 440 } // namespace task_manager | 477 } // namespace task_manager |
| OLD | NEW |