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/panel_resource_provider.h"
7 #include "base/i18n/rtl.h"
8 #include "chrome/browser/chrome_notification_types.h"
9 #include "chrome/browser/extensions/extension_service.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 "chrome/browser/ui/panels/panel.h"
16 #include "chrome/browser/ui/panels/panel_manager.h"
17 #include "chrome/common/extensions/extension.h"
18 #include "content/public/browser/notification_service.h"
19 #include "content/public/browser/render_process_host.h"
20 #include "content/public/browser/render_view_host.h"
21 #include "content/public/browser/web_contents.h"
22 #include "extensions/browser/view_type_utils.h"
23 #include "ui/base/l10n/l10n_util.h"
25 using content::RenderProcessHost;
26 using content::RenderViewHost;
27 using content::WebContents;
28 using extensions::Extension;
30 namespace task_manager {
32 class PanelResource : public RendererResource {
34 explicit PanelResource(Panel* panel);
35 virtual ~PanelResource();
38 virtual Type GetType() const OVERRIDE;
39 virtual string16 GetTitle() const OVERRIDE;
40 virtual string16 GetProfileName() const OVERRIDE;
41 virtual gfx::ImageSkia GetIcon() const OVERRIDE;
42 virtual content::WebContents* GetWebContents() const OVERRIDE;
43 virtual const extensions::Extension* GetExtension() const OVERRIDE;
47 // Determines prefix for title reflecting whether extensions are apps
48 // or in incognito mode.
49 int message_prefix_id_;
51 DISALLOW_COPY_AND_ASSIGN(PanelResource);
54 PanelResource::PanelResource(Panel* panel)
56 panel->GetWebContents()->GetRenderProcessHost()->GetHandle(),
57 panel->GetWebContents()->GetRenderViewHost()),
59 message_prefix_id_ = util::GetMessagePrefixID(
60 GetExtension()->is_app(),
62 panel->profile()->IsOffTheRecord(),
63 false, // is_prerender
64 false, // is_instant_overlay
65 false); // is_background
68 PanelResource::~PanelResource() {
71 Resource::Type PanelResource::GetType() const {
75 string16 PanelResource::GetTitle() const {
76 string16 title = panel_->GetWindowTitle();
77 // Since the title will be concatenated with an IDS_TASK_MANAGER_* prefix
78 // we need to explicitly set the title to be LTR format if there is no
79 // strong RTL charater in it. Otherwise, if the task manager prefix is an
80 // RTL word, the concatenated result might be wrong. For example,
81 // a page whose title is "Yahoo! Mail: The best web-based Email!", without
82 // setting it explicitly as LTR format, the concatenated result will be
83 // "!Yahoo! Mail: The best web-based Email :PPA", in which the capital
84 // letters "PPA" stands for the Hebrew word for "app".
85 base::i18n::AdjustStringForLocaleDirection(&title);
87 return l10n_util::GetStringFUTF16(message_prefix_id_, title);
90 string16 PanelResource::GetProfileName() const {
91 return util::GetProfileNameFromInfoCache(panel_->profile());
94 gfx::ImageSkia PanelResource::GetIcon() const {
95 gfx::Image icon = panel_->GetCurrentPageIcon();
96 return icon.IsEmpty() ? gfx::ImageSkia() : *icon.ToImageSkia();
99 WebContents* PanelResource::GetWebContents() const {
100 return panel_->GetWebContents();
103 const Extension* PanelResource::GetExtension() const {
104 ExtensionService* extension_service =
105 panel_->profile()->GetExtensionService();
106 return extension_service->extensions()->GetByID(panel_->extension_id());
109 ////////////////////////////////////////////////////////////////////////////////
110 // PanelResourceProvider class
111 ////////////////////////////////////////////////////////////////////////////////
113 PanelResourceProvider::PanelResourceProvider(TaskManager* task_manager)
115 task_manager_(task_manager) {
118 PanelResourceProvider::~PanelResourceProvider() {
121 Resource* PanelResourceProvider::GetResource(
123 int render_process_host_id,
125 // If an origin PID was specified, the request is from a plugin, not the
126 // render view host process
130 for (PanelResourceMap::iterator i = resources_.begin();
131 i != resources_.end(); ++i) {
132 WebContents* contents = i->first->GetWebContents();
134 contents->GetRenderProcessHost()->GetID() == render_process_host_id &&
135 contents->GetRenderViewHost()->GetRoutingID() == routing_id) {
140 // Can happen if the panel went away while a network request was being
145 void PanelResourceProvider::StartUpdating() {
149 // Add all the Panels.
150 std::vector<Panel*> panels = PanelManager::GetInstance()->panels();
151 for (size_t i = 0; i < panels.size(); ++i)
154 // Then we register for notifications to get new and remove closed panels.
155 registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_CONNECTED,
156 content::NotificationService::AllSources());
157 registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED,
158 content::NotificationService::AllSources());
161 void PanelResourceProvider::StopUpdating() {
165 // Unregister for notifications about new/removed panels.
166 registrar_.Remove(this, content::NOTIFICATION_WEB_CONTENTS_CONNECTED,
167 content::NotificationService::AllSources());
168 registrar_.Remove(this, content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED,
169 content::NotificationService::AllSources());
171 // Delete all the resources.
172 STLDeleteContainerPairSecondPointers(resources_.begin(), resources_.end());
176 void PanelResourceProvider::Add(Panel* panel) {
180 PanelResourceMap::const_iterator iter = resources_.find(panel);
181 if (iter != resources_.end())
184 PanelResource* resource = new PanelResource(panel);
185 resources_[panel] = resource;
186 task_manager_->AddResource(resource);
189 void PanelResourceProvider::Remove(Panel* panel) {
193 PanelResourceMap::iterator iter = resources_.find(panel);
194 if (iter == resources_.end())
197 PanelResource* resource = iter->second;
198 task_manager_->RemoveResource(resource);
199 resources_.erase(iter);
203 void PanelResourceProvider::Observe(int type,
204 const content::NotificationSource& source,
205 const content::NotificationDetails& details) {
206 WebContents* web_contents = content::Source<WebContents>(source).ptr();
207 if (extensions::GetViewType(web_contents) != extensions::VIEW_TYPE_PANEL)
211 case content::NOTIFICATION_WEB_CONTENTS_CONNECTED:
213 std::vector<Panel*>panels = PanelManager::GetInstance()->panels();
214 for (size_t i = 0; i < panels.size(); ++i) {
215 if (panels[i]->GetWebContents() == web_contents) {
222 case content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED:
224 for (PanelResourceMap::iterator iter = resources_.begin();
225 iter != resources_.end(); ++iter) {
226 Panel* panel = iter->first;
227 WebContents* panel_contents = panel->GetWebContents();
228 if (!panel_contents || panel_contents == web_contents) {
236 NOTREACHED() << "Unexpected notificiation.";
241 } // namespace task_manager