Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / task_manager / guest_resource_provider.cc
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.
4
5 #include "chrome/browser/task_manager/guest_resource_provider.h"
6
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"
26
27 using content::RenderProcessHost;
28 using content::RenderViewHost;
29 using content::RenderWidgetHost;
30 using content::WebContents;
31 using extensions::Extension;
32
33 namespace task_manager {
34
35 class GuestResource : public RendererResource {
36  public:
37   explicit GuestResource(content::RenderViewHost* render_view_host);
38   virtual ~GuestResource();
39
40   // Resource methods:
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;
47
48  private:
49   DISALLOW_COPY_AND_ASSIGN(GuestResource);
50 };
51
52 GuestResource::GuestResource(RenderViewHost* render_view_host)
53     : RendererResource(
54           render_view_host->GetSiteInstance()->GetProcess()->GetHandle(),
55           render_view_host) {
56 }
57
58 GuestResource::~GuestResource() {
59 }
60
61 Resource::Type GuestResource::GetType() const {
62   return GUEST;
63 }
64
65 base::string16 GuestResource::GetTitle() const {
66   WebContents* web_contents = GetWebContents();
67   const int message_id = IDS_TASK_MANAGER_WEBVIEW_TAG_PREFIX;
68   if (web_contents) {
69     base::string16 title = util::GetTitleFromWebContents(web_contents);
70     return l10n_util::GetStringFUTF16(message_id, title);
71   }
72   return l10n_util::GetStringFUTF16(message_id, base::string16());
73 }
74
75 base::string16 GuestResource::GetProfileName() const {
76   WebContents* web_contents = GetWebContents();
77   if (web_contents) {
78     Profile* profile = Profile::FromBrowserContext(
79         web_contents->GetBrowserContext());
80     return util::GetProfileNameFromInfoCache(profile);
81   }
82   return base::string16();
83 }
84
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();
90   }
91   return gfx::ImageSkia();
92 }
93
94 WebContents* GuestResource::GetWebContents() const {
95   return WebContents::FromRenderViewHost(render_view_host());
96 }
97
98 const Extension* GuestResource::GetExtension() const {
99   return NULL;
100 }
101
102 GuestResourceProvider::GuestResourceProvider(TaskManager* task_manager)
103     :  updating_(false),
104        task_manager_(task_manager) {
105 }
106
107 GuestResourceProvider::~GuestResourceProvider() {
108 }
109
110 Resource* GuestResourceProvider::GetResource(
111     int origin_pid,
112     int child_id,
113     int route_id) {
114   // If an origin PID was specified then the request originated in a plugin
115   // working on the WebContents's behalf, so ignore it.
116   if (origin_pid)
117     return NULL;
118
119   content::RenderFrameHost* rfh =
120       content::RenderFrameHost::FromID(child_id, route_id);
121   content::WebContents* web_contents =
122       content::WebContents::FromRenderFrameHost(rfh);
123
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)
128       return i->second;
129   }
130
131   return NULL;
132 }
133
134 void GuestResourceProvider::StartUpdating() {
135   DCHECK(!updating_);
136   updating_ = true;
137
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 && web_contents->IsSubframe())
146         Add(rvh);
147     }
148   }
149
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());
155 }
156
157 void GuestResourceProvider::StopUpdating() {
158   DCHECK(updating_);
159   updating_ = false;
160
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());
166
167   // Delete all the resources.
168   STLDeleteContainerPairSecondPointers(resources_.begin(), resources_.end());
169
170   resources_.clear();
171 }
172
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);
177 }
178
179 void GuestResourceProvider::Remove(RenderViewHost* render_view_host) {
180   if (!updating_)
181     return;
182
183   GuestResourceMap::iterator iter = resources_.find(render_view_host);
184   if (iter == resources_.end())
185     return;
186
187   GuestResource* resource = iter->second;
188   task_manager_->RemoveResource(resource);
189   resources_.erase(iter);
190   delete resource;
191 }
192
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())
198     return;
199
200   switch (type) {
201     case content::NOTIFICATION_WEB_CONTENTS_CONNECTED:
202       Add(web_contents->GetRenderViewHost());
203       break;
204     case content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED:
205       Remove(web_contents->GetRenderViewHost());
206       break;
207     default:
208       NOTREACHED() << "Unexpected notification.";
209   }
210 }
211
212 }  // namespace task_manager