- add sources.
[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_process_host.h"
17 #include "content/public/browser/render_view_host.h"
18 #include "content/public/browser/render_widget_host_iterator.h"
19 #include "content/public/browser/site_instance.h"
20 #include "content/public/browser/web_contents.h"
21 #include "grit/generated_resources.h"
22 #include "ui/base/l10n/l10n_util.h"
23 #include "ui/gfx/image/image.h"
24 #include "ui/gfx/image/image_skia.h"
25
26 using content::RenderProcessHost;
27 using content::RenderViewHost;
28 using content::RenderWidgetHost;
29 using content::WebContents;
30 using extensions::Extension;
31
32 namespace task_manager {
33
34 class GuestResource : public RendererResource {
35  public:
36   explicit GuestResource(content::RenderViewHost* render_view_host);
37   virtual ~GuestResource();
38
39   // Resource methods:
40   virtual Type GetType() const OVERRIDE;
41   virtual string16 GetTitle() const OVERRIDE;
42   virtual string16 GetProfileName() const OVERRIDE;
43   virtual gfx::ImageSkia GetIcon() const OVERRIDE;
44   virtual content::WebContents* GetWebContents() const OVERRIDE;
45   virtual const extensions::Extension* GetExtension() const OVERRIDE;
46
47  private:
48   DISALLOW_COPY_AND_ASSIGN(GuestResource);
49 };
50
51 GuestResource::GuestResource(RenderViewHost* render_view_host)
52     : RendererResource(
53           render_view_host->GetSiteInstance()->GetProcess()->GetHandle(),
54           render_view_host) {
55 }
56
57 GuestResource::~GuestResource() {
58 }
59
60 Resource::Type GuestResource::GetType() const {
61   return GUEST;
62 }
63
64 string16 GuestResource::GetTitle() const {
65   WebContents* web_contents = GetWebContents();
66   const int message_id = IDS_TASK_MANAGER_WEBVIEW_TAG_PREFIX;
67   if (web_contents) {
68     string16 title = util::GetTitleFromWebContents(web_contents);
69     return l10n_util::GetStringFUTF16(message_id, title);
70   }
71   return l10n_util::GetStringFUTF16(message_id, string16());
72 }
73
74 string16 GuestResource::GetProfileName() const {
75   WebContents* web_contents = GetWebContents();
76   if (web_contents) {
77     Profile* profile = Profile::FromBrowserContext(
78         web_contents->GetBrowserContext());
79     return util::GetProfileNameFromInfoCache(profile);
80   }
81   return string16();
82 }
83
84 gfx::ImageSkia GuestResource::GetIcon() const {
85   WebContents* web_contents = GetWebContents();
86   if (web_contents && FaviconTabHelper::FromWebContents(web_contents)) {
87     return FaviconTabHelper::FromWebContents(web_contents)->
88         GetFavicon().AsImageSkia();
89   }
90   return gfx::ImageSkia();
91 }
92
93 WebContents* GuestResource::GetWebContents() const {
94   return WebContents::FromRenderViewHost(render_view_host());
95 }
96
97 const Extension* GuestResource::GetExtension() const {
98   return NULL;
99 }
100
101 GuestResourceProvider::GuestResourceProvider(TaskManager* task_manager)
102     :  updating_(false),
103        task_manager_(task_manager) {
104 }
105
106 GuestResourceProvider::~GuestResourceProvider() {
107 }
108
109 Resource* GuestResourceProvider::GetResource(
110     int origin_pid,
111     int render_process_host_id,
112     int routing_id) {
113   // If an origin PID was specified then the request originated in a plugin
114   // working on the WebContents's behalf, so ignore it.
115   if (origin_pid)
116     return NULL;
117
118   for (GuestResourceMap::iterator i = resources_.begin();
119        i != resources_.end(); ++i) {
120     WebContents* contents = WebContents::FromRenderViewHost(i->first);
121     if (contents &&
122         contents->GetRenderProcessHost()->GetID() == render_process_host_id &&
123         contents->GetRenderViewHost()->GetRoutingID() == routing_id) {
124       return i->second;
125     }
126   }
127
128   return NULL;
129 }
130
131 void GuestResourceProvider::StartUpdating() {
132   DCHECK(!updating_);
133   updating_ = true;
134
135   // Add all the existing guest WebContents.
136   scoped_ptr<content::RenderWidgetHostIterator> widgets(
137       RenderWidgetHost::GetRenderWidgetHosts());
138   while (content::RenderWidgetHost* widget = widgets->GetNextHost()) {
139     if (widget->IsRenderView()) {
140       RenderViewHost* rvh = RenderViewHost::From(widget);
141       if (rvh->IsSubframe())
142         Add(rvh);
143     }
144   }
145
146   // Then we register for notifications to get new guests.
147   registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_CONNECTED,
148       content::NotificationService::AllBrowserContextsAndSources());
149   registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED,
150       content::NotificationService::AllBrowserContextsAndSources());
151 }
152
153 void GuestResourceProvider::StopUpdating() {
154   DCHECK(updating_);
155   updating_ = false;
156
157   // Unregister for notifications.
158   registrar_.Remove(this, content::NOTIFICATION_WEB_CONTENTS_CONNECTED,
159       content::NotificationService::AllBrowserContextsAndSources());
160   registrar_.Remove(this, content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED,
161       content::NotificationService::AllBrowserContextsAndSources());
162
163   // Delete all the resources.
164   STLDeleteContainerPairSecondPointers(resources_.begin(), resources_.end());
165
166   resources_.clear();
167 }
168
169 void GuestResourceProvider::Add(RenderViewHost* render_view_host) {
170   GuestResource* resource = new GuestResource(render_view_host);
171   resources_[render_view_host] = resource;
172   task_manager_->AddResource(resource);
173 }
174
175 void GuestResourceProvider::Remove(RenderViewHost* render_view_host) {
176   if (!updating_)
177     return;
178
179   GuestResourceMap::iterator iter = resources_.find(render_view_host);
180   if (iter == resources_.end())
181     return;
182
183   GuestResource* resource = iter->second;
184   task_manager_->RemoveResource(resource);
185   resources_.erase(iter);
186   delete resource;
187 }
188
189 void GuestResourceProvider::Observe(int type,
190     const content::NotificationSource& source,
191     const content::NotificationDetails& details) {
192   WebContents* web_contents = content::Source<WebContents>(source).ptr();
193   if (!web_contents || !web_contents->GetRenderViewHost()->IsSubframe())
194     return;
195
196   switch (type) {
197     case content::NOTIFICATION_WEB_CONTENTS_CONNECTED:
198       Add(web_contents->GetRenderViewHost());
199       break;
200     case content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED:
201       Remove(web_contents->GetRenderViewHost());
202       break;
203     default:
204       NOTREACHED() << "Unexpected notification.";
205   }
206 }
207
208 }  // namespace task_manager