Cast: Stop logging kVideoFrameSentToEncoder and rename a couple events.
[chromium-blink-merge.git] / chrome / browser / task_manager / web_contents_resource_provider.cc
blobb29dd88c76e0c3ca9a5e127866e271567d12b226
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/task_manager/web_contents_resource_provider.h"
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "chrome/browser/browser_process.h"
10 #include "chrome/browser/prerender/prerender_manager.h"
11 #include "chrome/browser/prerender/prerender_manager_factory.h"
12 #include "chrome/browser/profiles/profile.h"
13 #include "chrome/browser/profiles/profile_manager.h"
14 #include "chrome/browser/task_manager/renderer_resource.h"
15 #include "chrome/browser/task_manager/task_manager.h"
16 #include "chrome/browser/task_manager/task_manager_util.h"
17 #include "chrome/browser/task_manager/web_contents_information.h"
18 #include "content/public/browser/render_frame_host.h"
19 #include "content/public/browser/render_process_host.h"
20 #include "content/public/browser/render_view_host.h"
21 #include "content/public/browser/render_widget_host_iterator.h"
22 #include "content/public/browser/web_contents.h"
23 #include "content/public/browser/web_contents_observer.h"
25 using content::WebContents;
26 using content::RenderViewHost;
28 namespace task_manager {
30 // A WebContentsObserver that tracks changes to a WebContents on behalf of
31 // a WebContentsResourceProvider.
32 class TaskManagerWebContentsObserver : public content::WebContentsObserver {
33 public:
34 TaskManagerWebContentsObserver(WebContents* web_contents,
35 WebContentsResourceProvider* provider)
36 : content::WebContentsObserver(web_contents), provider_(provider) {}
38 // content::WebContentsObserver implementation.
39 virtual void RenderViewHostChanged(RenderViewHost* old_host,
40 RenderViewHost* new_host) OVERRIDE {
41 provider_->RemoveFromTaskManager(web_contents());
42 provider_->AddToTaskManager(web_contents());
45 virtual void RenderViewReady() OVERRIDE {
46 provider_->RemoveFromTaskManager(web_contents());
47 provider_->AddToTaskManager(web_contents());
50 virtual void RenderProcessGone(base::TerminationStatus status) OVERRIDE {
51 provider_->RemoveFromTaskManager(web_contents());
54 virtual void WebContentsDestroyed(WebContents* web_contents) OVERRIDE {
55 provider_->RemoveFromTaskManager(web_contents);
56 provider_->DeleteObserver(this); // Deletes |this|.
59 private:
60 WebContentsResourceProvider* provider_;
63 ////////////////////////////////////////////////////////////////////////////////
64 // WebContentsResourceProvider class
65 ////////////////////////////////////////////////////////////////////////////////
67 WebContentsResourceProvider::WebContentsResourceProvider(
68 TaskManager* task_manager,
69 scoped_ptr<WebContentsInformation> info)
70 : updating_(false), task_manager_(task_manager), info_(info.Pass()) {}
72 WebContentsResourceProvider::~WebContentsResourceProvider() {}
74 RendererResource* WebContentsResourceProvider::GetResource(int origin_pid,
75 int child_id,
76 int route_id) {
77 content::RenderFrameHost* rfh =
78 content::RenderFrameHost::FromID(child_id, route_id);
79 content::WebContents* web_contents =
80 content::WebContents::FromRenderFrameHost(rfh);
82 // If an origin PID was specified then the request originated in a plugin
83 // working on the WebContents's behalf, so ignore it.
84 if (origin_pid)
85 return NULL;
87 std::map<WebContents*, RendererResource*>::iterator res_iter =
88 resources_.find(web_contents);
90 if (res_iter == resources_.end()) {
91 // Can happen if the tab was closed while a network request was being
92 // performed.
93 return NULL;
95 return res_iter->second;
98 void WebContentsResourceProvider::StartUpdating() {
99 DCHECK(!updating_);
100 updating_ = true;
102 WebContentsInformation::NewWebContentsCallback new_web_contents_callback =
103 base::Bind(&WebContentsResourceProvider::OnWebContentsCreated, this);
104 info_->GetAll(new_web_contents_callback);
105 info_->StartObservingCreation(new_web_contents_callback);
108 void WebContentsResourceProvider::StopUpdating() {
109 DCHECK(updating_);
110 updating_ = false;
112 info_->StopObservingCreation();
114 // Delete all observers; this dissassociates them from the WebContents too.
115 STLDeleteElements(&web_contents_observers_);
116 web_contents_observers_.clear();
118 // Delete all resources. We don't need to remove them from the TaskManager,
119 // because it's the TaskManager that's asking us to StopUpdating().
120 STLDeleteValues(&resources_);
121 resources_.clear();
124 void WebContentsResourceProvider::OnWebContentsCreated(
125 WebContents* web_contents) {
126 // Don't add dead tabs or tabs that haven't yet connected.
127 if (!web_contents->GetRenderProcessHost()->GetHandle() ||
128 !web_contents->WillNotifyDisconnection()) {
129 return;
132 DCHECK(info_->CheckOwnership(web_contents));
133 if (AddToTaskManager(web_contents)) {
134 web_contents_observers_.insert(
135 new TaskManagerWebContentsObserver(web_contents, this));
139 bool WebContentsResourceProvider::AddToTaskManager(WebContents* web_contents) {
140 if (!updating_)
141 return false;
143 if (resources_.count(web_contents)) {
144 // The case may happen that we have added a WebContents as part of the
145 // iteration performed during StartUpdating() call but the notification that
146 // it has connected was not fired yet. So when the notification happens, we
147 // are already observing this WebContents and just ignore it.
148 return false;
151 // TODO(nick): If the RenderView is not live, then do we still want to install
152 // the WebContentsObserver? Only some of the original ResourceProviders
153 // had that check.
154 scoped_ptr<RendererResource> resource = info_->MakeResource(web_contents);
155 if (!resource)
156 return false;
158 task_manager_->AddResource(resource.get());
159 resources_[web_contents] = resource.release();
160 return true;
163 void WebContentsResourceProvider::RemoveFromTaskManager(
164 WebContents* web_contents) {
165 if (!updating_)
166 return;
168 std::map<WebContents*, RendererResource*>::iterator resource_iter =
169 resources_.find(web_contents);
171 if (resource_iter == resources_.end()) {
172 return;
175 RendererResource* resource = resource_iter->second;
176 task_manager_->RemoveResource(resource);
178 // Remove the resource from the Task Manager.
179 // And from the provider.
180 resources_.erase(resource_iter);
182 // Finally, delete the resource.
183 delete resource;
186 void WebContentsResourceProvider::DeleteObserver(
187 TaskManagerWebContentsObserver* observer) {
188 if (!web_contents_observers_.erase(observer)) {
189 NOTREACHED();
190 return;
192 delete observer; // Typically, this is our caller. Deletion is okay.
195 } // namespace task_manager