Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(209)

Side by Side Diff: chrome/browser/task_manager/task_manager_tab_contents_resource_provider.cc

Issue 15196003: Create task_manager namespace and wrap classes related to TaskManager with it. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2012 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.
4
5 #include "chrome/browser/task_manager/task_manager_tab_contents_resource_provide r.h"
6
7 #include "chrome/browser/browser_process.h"
8 #include "chrome/browser/extensions/extension_service.h"
9 #include "chrome/browser/favicon/favicon_tab_helper.h"
10 #include "chrome/browser/prerender/prerender_manager.h"
11 #include "chrome/browser/prerender/prerender_manager_factory.h"
12 #include "chrome/browser/printing/background_printing_manager.h"
13 #include "chrome/browser/profiles/profile.h"
14 #include "chrome/browser/profiles/profile_manager.h"
15 #include "chrome/browser/tab_contents/tab_util.h"
16 #include "chrome/browser/task_manager/task_manager_render_resource.h"
17 #include "chrome/browser/task_manager/task_manager_resource_util.h"
18 #include "chrome/browser/ui/browser.h"
19 #include "chrome/browser/ui/browser_finder.h"
20 #include "chrome/browser/ui/browser_instant_controller.h"
21 #include "chrome/browser/ui/browser_iterator.h"
22 #include "chrome/browser/ui/tab_contents/tab_contents_iterator.h"
23 #include "chrome/common/chrome_notification_types.h"
24 #include "content/public/browser/notification_service.h"
25 #include "content/public/browser/render_process_host.h"
26 #include "content/public/browser/web_contents.h"
27 #include "extensions/common/constants.h"
28 #include "grit/theme_resources.h"
29 #include "ui/base/l10n/l10n_util.h"
30 #include "ui/base/resource/resource_bundle.h"
31 #include "ui/gfx/image/image_skia.h"
32
33 using content::WebContents;
34 using extensions::Extension;
35
36
37 namespace {
38
39 bool IsContentsPrerendering(WebContents* web_contents) {
40 Profile* profile =
41 Profile::FromBrowserContext(web_contents->GetBrowserContext());
42 prerender::PrerenderManager* prerender_manager =
43 prerender::PrerenderManagerFactory::GetForProfile(profile);
44 return prerender_manager &&
45 prerender_manager->IsWebContentsPrerendering(web_contents, NULL);
46 }
47
48 bool IsContentsInstant(WebContents* web_contents) {
49 for (chrome::BrowserIterator it; !it.done(); it.Next()) {
50 if (it->instant_controller() &&
51 it->instant_controller()->instant()->
52 GetOverlayContents() == web_contents) {
53 return true;
54 }
55 }
56
57 return false;
58 }
59
60 bool IsContentsBackgroundPrinted(WebContents* web_contents) {
61 printing::BackgroundPrintingManager* printing_manager =
62 g_browser_process->background_printing_manager();
63 return printing_manager->HasPrintPreviewDialog(web_contents);
64 }
65
66 } // namespace
67
68 // Tracks a single tab contents, prerendered page, Instant page, or background
69 // printing page.
70 class TaskManagerTabContentsResource : public TaskManagerRendererResource {
71 public:
72 explicit TaskManagerTabContentsResource(content::WebContents* web_contents);
73 virtual ~TaskManagerTabContentsResource();
74
75 // Called when the underlying web_contents has been committed and is no
76 // longer an Instant overlay.
77 void InstantCommitted();
78
79 // TaskManager::Resource methods:
80 virtual Type GetType() const OVERRIDE;
81 virtual string16 GetTitle() const OVERRIDE;
82 virtual string16 GetProfileName() const OVERRIDE;
83 virtual gfx::ImageSkia GetIcon() const OVERRIDE;
84 virtual content::WebContents* GetWebContents() const OVERRIDE;
85 virtual const extensions::Extension* GetExtension() const OVERRIDE;
86
87 private:
88 // Returns true if contains content rendered by an extension.
89 bool HostsExtension() const;
90
91 static gfx::ImageSkia* prerender_icon_;
92 content::WebContents* web_contents_;
93 Profile* profile_;
94 bool is_instant_overlay_;
95
96 DISALLOW_COPY_AND_ASSIGN(TaskManagerTabContentsResource);
97 };
98
99 gfx::ImageSkia* TaskManagerTabContentsResource::prerender_icon_ = NULL;
100
101 TaskManagerTabContentsResource::TaskManagerTabContentsResource(
102 WebContents* web_contents)
103 : TaskManagerRendererResource(
104 web_contents->GetRenderProcessHost()->GetHandle(),
105 web_contents->GetRenderViewHost()),
106 web_contents_(web_contents),
107 profile_(Profile::FromBrowserContext(web_contents->GetBrowserContext())),
108 is_instant_overlay_(IsContentsInstant(web_contents)) {
109 if (!prerender_icon_) {
110 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
111 prerender_icon_ = rb.GetImageSkiaNamed(IDR_PRERENDER);
112 }
113 }
114
115 TaskManagerTabContentsResource::~TaskManagerTabContentsResource() {
116 }
117
118 void TaskManagerTabContentsResource::InstantCommitted() {
119 DCHECK(is_instant_overlay_);
120 is_instant_overlay_ = false;
121 }
122
123 bool TaskManagerTabContentsResource::HostsExtension() const {
124 return web_contents_->GetURL().SchemeIs(extensions::kExtensionScheme);
125 }
126
127 TaskManager::Resource::Type TaskManagerTabContentsResource::GetType() const {
128 return HostsExtension() ? EXTENSION : RENDERER;
129 }
130
131 string16 TaskManagerTabContentsResource::GetTitle() const {
132 // Fall back on the URL if there's no title.
133 GURL url = web_contents_->GetURL();
134 string16 tab_title =
135 TaskManagerResourceUtil::GetTitleFromWebContents(web_contents_);
136
137 // Only classify as an app if the URL is an app and the tab is hosting an
138 // extension process. (It's possible to be showing the URL from before it
139 // was installed as an app.)
140 ExtensionService* extension_service = profile_->GetExtensionService();
141 extensions::ProcessMap* process_map = extension_service->process_map();
142 bool is_app = extension_service->IsInstalledApp(url) &&
143 process_map->Contains(web_contents_->GetRenderProcessHost()->GetID());
144
145 int message_id = TaskManagerResourceUtil::GetMessagePrefixID(
146 is_app,
147 HostsExtension(),
148 profile_->IsOffTheRecord(),
149 IsContentsPrerendering(web_contents_),
150 is_instant_overlay_,
151 false); // is_background
152 return l10n_util::GetStringFUTF16(message_id, tab_title);
153 }
154
155 string16 TaskManagerTabContentsResource::GetProfileName() const {
156 return TaskManagerResourceUtil::GetProfileNameFromInfoCache(profile_);
157 }
158
159 gfx::ImageSkia TaskManagerTabContentsResource::GetIcon() const {
160 if (IsContentsPrerendering(web_contents_))
161 return *prerender_icon_;
162 return FaviconTabHelper::FromWebContents(web_contents_)->
163 GetFavicon().AsImageSkia();
164 }
165
166 WebContents* TaskManagerTabContentsResource::GetWebContents() const {
167 return web_contents_;
168 }
169
170 const Extension* TaskManagerTabContentsResource::GetExtension() const {
171 if (HostsExtension()) {
172 ExtensionService* extension_service = profile_->GetExtensionService();
173 return extension_service->extensions()->GetByID(
174 web_contents_->GetURL().host());
175 }
176
177 return NULL;
178 }
179
180 ////////////////////////////////////////////////////////////////////////////////
181 // TaskManagerTabContentsResourceProvider class
182 ////////////////////////////////////////////////////////////////////////////////
183
184 TaskManagerTabContentsResourceProvider::
185 TaskManagerTabContentsResourceProvider(TaskManager* task_manager)
186 : updating_(false),
187 task_manager_(task_manager) {
188 }
189
190 TaskManagerTabContentsResourceProvider::
191 ~TaskManagerTabContentsResourceProvider() {
192 }
193
194 TaskManager::Resource* TaskManagerTabContentsResourceProvider::GetResource(
195 int origin_pid,
196 int render_process_host_id,
197 int routing_id) {
198 WebContents* web_contents =
199 tab_util::GetWebContentsByID(render_process_host_id, routing_id);
200 if (!web_contents) // Not one of our resource.
201 return NULL;
202
203 // If an origin PID was specified then the request originated in a plugin
204 // working on the WebContents's behalf, so ignore it.
205 if (origin_pid)
206 return NULL;
207
208 std::map<WebContents*, TaskManagerTabContentsResource*>::iterator
209 res_iter = resources_.find(web_contents);
210 if (res_iter == resources_.end()) {
211 // Can happen if the tab was closed while a network request was being
212 // performed.
213 return NULL;
214 }
215 return res_iter->second;
216 }
217
218 void TaskManagerTabContentsResourceProvider::StartUpdating() {
219 DCHECK(!updating_);
220 updating_ = true;
221
222 // The contents that are tracked by this resource provider are those that
223 // are tab contents (WebContents serving as a tab in a Browser), Instant
224 // pages, prerender pages, and background printed pages.
225
226 // Add all the existing WebContentses.
227 for (TabContentsIterator iterator; !iterator.done(); iterator.Next())
228 Add(*iterator);
229
230 // Add all the Instant pages.
231 for (chrome::BrowserIterator it; !it.done(); it.Next()) {
232 if (it->instant_controller() &&
233 it->instant_controller()->instant()->GetOverlayContents()) {
234 Add(it->instant_controller()->instant()->GetOverlayContents());
235 }
236 }
237
238 // Add all the prerender pages.
239 std::vector<Profile*> profiles(
240 g_browser_process->profile_manager()->GetLoadedProfiles());
241 for (size_t i = 0; i < profiles.size(); ++i) {
242 prerender::PrerenderManager* prerender_manager =
243 prerender::PrerenderManagerFactory::GetForProfile(profiles[i]);
244 if (prerender_manager) {
245 const std::vector<content::WebContents*> contentses =
246 prerender_manager->GetAllPrerenderingContents();
247 for (size_t j = 0; j < contentses.size(); ++j)
248 Add(contentses[j]);
249 }
250 }
251
252 // Add all the pages being background printed.
253 printing::BackgroundPrintingManager* printing_manager =
254 g_browser_process->background_printing_manager();
255 for (printing::BackgroundPrintingManager::WebContentsSet::iterator i =
256 printing_manager->begin();
257 i != printing_manager->end(); ++i) {
258 Add(*i);
259 }
260
261 // Then we register for notifications to get new web contents.
262 registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_CONNECTED,
263 content::NotificationService::AllBrowserContextsAndSources());
264 registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_SWAPPED,
265 content::NotificationService::AllBrowserContextsAndSources());
266 registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED,
267 content::NotificationService::AllBrowserContextsAndSources());
268 registrar_.Add(this, chrome::NOTIFICATION_INSTANT_COMMITTED,
269 content::NotificationService::AllBrowserContextsAndSources());
270 }
271
272 void TaskManagerTabContentsResourceProvider::StopUpdating() {
273 DCHECK(updating_);
274 updating_ = false;
275
276 // Then we unregister for notifications to get new web contents.
277 registrar_.Remove(this, content::NOTIFICATION_WEB_CONTENTS_CONNECTED,
278 content::NotificationService::AllBrowserContextsAndSources());
279 registrar_.Remove(this, content::NOTIFICATION_WEB_CONTENTS_SWAPPED,
280 content::NotificationService::AllBrowserContextsAndSources());
281 registrar_.Remove(this, content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED,
282 content::NotificationService::AllBrowserContextsAndSources());
283 registrar_.Remove(this, chrome::NOTIFICATION_INSTANT_COMMITTED,
284 content::NotificationService::AllBrowserContextsAndSources());
285
286 // Delete all the resources.
287 STLDeleteContainerPairSecondPointers(resources_.begin(), resources_.end());
288
289 resources_.clear();
290 }
291
292 void TaskManagerTabContentsResourceProvider::AddToTaskManager(
293 WebContents* web_contents) {
294 TaskManagerTabContentsResource* resource =
295 new TaskManagerTabContentsResource(web_contents);
296 resources_[web_contents] = resource;
297 task_manager_->AddResource(resource);
298 }
299
300 void TaskManagerTabContentsResourceProvider::Add(WebContents* web_contents) {
301 if (!updating_)
302 return;
303
304 // The contents that are tracked by this resource provider are those that
305 // are tab contents (WebContents serving as a tab in a Browser), Instant
306 // pages, prerender pages, and background printed pages.
307 if (!chrome::FindBrowserWithWebContents(web_contents) &&
308 !IsContentsPrerendering(web_contents) &&
309 !IsContentsInstant(web_contents) &&
310 !IsContentsBackgroundPrinted(web_contents)) {
311 return;
312 }
313
314 // Don't add dead tabs or tabs that haven't yet connected.
315 if (!web_contents->GetRenderProcessHost()->GetHandle() ||
316 !web_contents->WillNotifyDisconnection()) {
317 return;
318 }
319
320 if (resources_.count(web_contents)) {
321 // The case may happen that we have added a WebContents as part of the
322 // iteration performed during StartUpdating() call but the notification that
323 // it has connected was not fired yet. So when the notification happens, we
324 // already know about this tab and just ignore it.
325 return;
326 }
327 AddToTaskManager(web_contents);
328 }
329
330 void TaskManagerTabContentsResourceProvider::Remove(WebContents* web_contents) {
331 if (!updating_)
332 return;
333 std::map<WebContents*, TaskManagerTabContentsResource*>::iterator
334 iter = resources_.find(web_contents);
335 if (iter == resources_.end()) {
336 // Since WebContents are destroyed asynchronously (see TabContentsCollector
337 // in navigation_controller.cc), we can be notified of a tab being removed
338 // that we don't know. This can happen if the user closes a tab and quickly
339 // opens the task manager, before the tab is actually destroyed.
340 return;
341 }
342
343 // Remove the resource from the Task Manager.
344 TaskManagerTabContentsResource* resource = iter->second;
345 task_manager_->RemoveResource(resource);
346 // And from the provider.
347 resources_.erase(iter);
348 // Finally, delete the resource.
349 delete resource;
350 }
351
352 void TaskManagerTabContentsResourceProvider::InstantCommitted(
353 WebContents* web_contents) {
354 if (!updating_)
355 return;
356 std::map<WebContents*, TaskManagerTabContentsResource*>::iterator
357 iter = resources_.find(web_contents);
358 DCHECK(iter != resources_.end());
359 if (iter != resources_.end())
360 iter->second->InstantCommitted();
361 }
362
363 void TaskManagerTabContentsResourceProvider::Observe(
364 int type,
365 const content::NotificationSource& source,
366 const content::NotificationDetails& details) {
367 WebContents* web_contents = content::Source<WebContents>(source).ptr();
368
369 switch (type) {
370 case content::NOTIFICATION_WEB_CONTENTS_CONNECTED:
371 Add(web_contents);
372 break;
373 case content::NOTIFICATION_WEB_CONTENTS_SWAPPED:
374 Remove(web_contents);
375 Add(web_contents);
376 break;
377 case content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED:
378 Remove(web_contents);
379 break;
380 case chrome::NOTIFICATION_INSTANT_COMMITTED:
381 InstantCommitted(web_contents);
382 break;
383 default:
384 NOTREACHED() << "Unexpected notification.";
385 return;
386 }
387 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698