1 // Copyright 2013 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/guest_resource_provider.h"
7 #include "base/strings/string16.h"
8 #include "chrome/browser/chrome_notification_types.h"
9 #include "chrome/browser/favicon/favicon_tab_helper.h"
10 #include "chrome/browser/profiles/profile.h"
11 #include "chrome/browser/task_manager/renderer_resource.h"
12 #include "chrome/browser/task_manager/resource_provider.h"
13 #include "chrome/browser/task_manager/task_manager.h"
14 #include "chrome/browser/task_manager/task_manager_util.h"
15 #include "content/public/browser/notification_service.h"
16 #include "content/public/browser/render_frame_host.h"
17 #include "content/public/browser/render_process_host.h"
18 #include "content/public/browser/render_view_host.h"
19 #include "content/public/browser/render_widget_host_iterator.h"
20 #include "content/public/browser/site_instance.h"
21 #include "content/public/browser/web_contents.h"
22 #include "grit/generated_resources.h"
23 #include "ui/base/l10n/l10n_util.h"
24 #include "ui/gfx/image/image.h"
25 #include "ui/gfx/image/image_skia.h"
27 using content::RenderProcessHost
;
28 using content::RenderViewHost
;
29 using content::RenderWidgetHost
;
30 using content::WebContents
;
31 using extensions::Extension
;
33 namespace task_manager
{
35 class GuestResource
: public RendererResource
{
37 explicit GuestResource(content::RenderViewHost
* render_view_host
);
38 virtual ~GuestResource();
41 virtual Type
GetType() const OVERRIDE
;
42 virtual base::string16
GetTitle() const OVERRIDE
;
43 virtual base::string16
GetProfileName() const OVERRIDE
;
44 virtual gfx::ImageSkia
GetIcon() const OVERRIDE
;
45 virtual content::WebContents
* GetWebContents() const OVERRIDE
;
46 virtual const extensions::Extension
* GetExtension() const OVERRIDE
;
49 DISALLOW_COPY_AND_ASSIGN(GuestResource
);
52 GuestResource::GuestResource(RenderViewHost
* render_view_host
)
54 render_view_host
->GetSiteInstance()->GetProcess()->GetHandle(),
58 GuestResource::~GuestResource() {
61 Resource::Type
GuestResource::GetType() const {
65 base::string16
GuestResource::GetTitle() const {
66 WebContents
* web_contents
= GetWebContents();
67 const int message_id
= IDS_TASK_MANAGER_WEBVIEW_TAG_PREFIX
;
69 base::string16 title
= util::GetTitleFromWebContents(web_contents
);
70 return l10n_util::GetStringFUTF16(message_id
, title
);
72 return l10n_util::GetStringFUTF16(message_id
, base::string16());
75 base::string16
GuestResource::GetProfileName() const {
76 WebContents
* web_contents
= GetWebContents();
78 Profile
* profile
= Profile::FromBrowserContext(
79 web_contents
->GetBrowserContext());
80 return util::GetProfileNameFromInfoCache(profile
);
82 return base::string16();
85 gfx::ImageSkia
GuestResource::GetIcon() const {
86 WebContents
* web_contents
= GetWebContents();
87 if (web_contents
&& FaviconTabHelper::FromWebContents(web_contents
)) {
88 return FaviconTabHelper::FromWebContents(web_contents
)->
89 GetFavicon().AsImageSkia();
91 return gfx::ImageSkia();
94 WebContents
* GuestResource::GetWebContents() const {
95 return WebContents::FromRenderViewHost(render_view_host());
98 const Extension
* GuestResource::GetExtension() const {
102 GuestResourceProvider::GuestResourceProvider(TaskManager
* task_manager
)
104 task_manager_(task_manager
) {
107 GuestResourceProvider::~GuestResourceProvider() {
110 Resource
* GuestResourceProvider::GetResource(
114 // If an origin PID was specified then the request originated in a plugin
115 // working on the WebContents's behalf, so ignore it.
119 content::RenderFrameHost
* rfh
=
120 content::RenderFrameHost::FromID(child_id
, route_id
);
121 content::WebContents
* web_contents
=
122 content::WebContents::FromRenderFrameHost(rfh
);
124 for (GuestResourceMap::iterator i
= resources_
.begin();
125 i
!= resources_
.end(); ++i
) {
126 WebContents
* guest_contents
= WebContents::FromRenderViewHost(i
->first
);
127 if (web_contents
== guest_contents
)
134 void GuestResourceProvider::StartUpdating() {
138 // Add all the existing guest WebContents.
139 scoped_ptr
<content::RenderWidgetHostIterator
> widgets(
140 RenderWidgetHost::GetRenderWidgetHosts());
141 while (content::RenderWidgetHost
* widget
= widgets
->GetNextHost()) {
142 if (widget
->IsRenderView()) {
143 RenderViewHost
* rvh
= RenderViewHost::From(widget
);
144 WebContents
* web_contents
= WebContents::FromRenderViewHost(rvh
);
145 if (web_contents
->IsSubframe())
150 // Then we register for notifications to get new guests.
151 registrar_
.Add(this, content::NOTIFICATION_WEB_CONTENTS_CONNECTED
,
152 content::NotificationService::AllBrowserContextsAndSources());
153 registrar_
.Add(this, content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED
,
154 content::NotificationService::AllBrowserContextsAndSources());
157 void GuestResourceProvider::StopUpdating() {
161 // Unregister for notifications.
162 registrar_
.Remove(this, content::NOTIFICATION_WEB_CONTENTS_CONNECTED
,
163 content::NotificationService::AllBrowserContextsAndSources());
164 registrar_
.Remove(this, content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED
,
165 content::NotificationService::AllBrowserContextsAndSources());
167 // Delete all the resources.
168 STLDeleteContainerPairSecondPointers(resources_
.begin(), resources_
.end());
173 void GuestResourceProvider::Add(RenderViewHost
* render_view_host
) {
174 GuestResource
* resource
= new GuestResource(render_view_host
);
175 resources_
[render_view_host
] = resource
;
176 task_manager_
->AddResource(resource
);
179 void GuestResourceProvider::Remove(RenderViewHost
* render_view_host
) {
183 GuestResourceMap::iterator iter
= resources_
.find(render_view_host
);
184 if (iter
== resources_
.end())
187 GuestResource
* resource
= iter
->second
;
188 task_manager_
->RemoveResource(resource
);
189 resources_
.erase(iter
);
193 void GuestResourceProvider::Observe(int type
,
194 const content::NotificationSource
& source
,
195 const content::NotificationDetails
& details
) {
196 WebContents
* web_contents
= content::Source
<WebContents
>(source
).ptr();
197 if (!web_contents
|| !web_contents
->IsSubframe())
201 case content::NOTIFICATION_WEB_CONTENTS_CONNECTED
:
202 Add(web_contents
->GetRenderViewHost());
204 case content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED
:
205 Remove(web_contents
->GetRenderViewHost());
208 NOTREACHED() << "Unexpected notification.";
212 } // namespace task_manager