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 "content/public/browser/notification_service.h"
18 #include "content/public/browser/render_frame_host.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 "extensions/common/extension.h"
24 #include "ui/base/l10n/l10n_util.h"
26 using content::RenderProcessHost
;
27 using content::RenderViewHost
;
28 using content::WebContents
;
29 using extensions::Extension
;
31 namespace task_manager
{
33 class PanelResource
: public RendererResource
{
35 explicit PanelResource(Panel
* panel
);
36 virtual ~PanelResource();
39 virtual Type
GetType() const OVERRIDE
;
40 virtual base::string16
GetTitle() const OVERRIDE
;
41 virtual base::string16
GetProfileName() const OVERRIDE
;
42 virtual gfx::ImageSkia
GetIcon() const OVERRIDE
;
43 virtual content::WebContents
* GetWebContents() const OVERRIDE
;
44 virtual const extensions::Extension
* GetExtension() const OVERRIDE
;
48 // Determines prefix for title reflecting whether extensions are apps
49 // or in incognito mode.
50 int message_prefix_id_
;
52 DISALLOW_COPY_AND_ASSIGN(PanelResource
);
55 PanelResource::PanelResource(Panel
* panel
)
57 panel
->GetWebContents()->GetRenderProcessHost()->GetHandle(),
58 panel
->GetWebContents()->GetRenderViewHost()),
60 message_prefix_id_
= util::GetMessagePrefixID(
61 GetExtension()->is_app(),
63 panel
->profile()->IsOffTheRecord(),
64 false, // is_prerender
65 false); // is_background
68 PanelResource::~PanelResource() {
71 Resource::Type
PanelResource::GetType() const {
75 base::string16
PanelResource::GetTitle() const {
76 base::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 base::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(
125 // If an origin PID was specified, the request is from a plugin, not the
126 // render view host process
130 content::RenderFrameHost
* rfh
=
131 content::RenderFrameHost::FromID(child_id
, route_id
);
132 content::WebContents
* web_contents
=
133 content::WebContents::FromRenderFrameHost(rfh
);
135 for (PanelResourceMap::iterator i
= resources_
.begin();
136 i
!= resources_
.end(); ++i
) {
137 if (web_contents
== i
->first
->GetWebContents())
141 // Can happen if the panel went away while a network request was being
146 void PanelResourceProvider::StartUpdating() {
150 // Add all the Panels.
151 std::vector
<Panel
*> panels
= PanelManager::GetInstance()->panels();
152 for (size_t i
= 0; i
< panels
.size(); ++i
)
155 // Then we register for notifications to get new and remove closed panels.
156 registrar_
.Add(this, content::NOTIFICATION_WEB_CONTENTS_CONNECTED
,
157 content::NotificationService::AllSources());
158 registrar_
.Add(this, content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED
,
159 content::NotificationService::AllSources());
162 void PanelResourceProvider::StopUpdating() {
166 // Unregister for notifications about new/removed panels.
167 registrar_
.Remove(this, content::NOTIFICATION_WEB_CONTENTS_CONNECTED
,
168 content::NotificationService::AllSources());
169 registrar_
.Remove(this, content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED
,
170 content::NotificationService::AllSources());
172 // Delete all the resources.
173 STLDeleteContainerPairSecondPointers(resources_
.begin(), resources_
.end());
177 void PanelResourceProvider::Add(Panel
* panel
) {
181 PanelResourceMap::const_iterator iter
= resources_
.find(panel
);
182 if (iter
!= resources_
.end())
185 PanelResource
* resource
= new PanelResource(panel
);
186 resources_
[panel
] = resource
;
187 task_manager_
->AddResource(resource
);
190 void PanelResourceProvider::Remove(Panel
* panel
) {
194 PanelResourceMap::iterator iter
= resources_
.find(panel
);
195 if (iter
== resources_
.end())
198 PanelResource
* resource
= iter
->second
;
199 task_manager_
->RemoveResource(resource
);
200 resources_
.erase(iter
);
204 void PanelResourceProvider::Observe(int type
,
205 const content::NotificationSource
& source
,
206 const content::NotificationDetails
& details
) {
207 WebContents
* web_contents
= content::Source
<WebContents
>(source
).ptr();
208 if (extensions::GetViewType(web_contents
) != extensions::VIEW_TYPE_PANEL
)
212 case content::NOTIFICATION_WEB_CONTENTS_CONNECTED
:
214 std::vector
<Panel
*>panels
= PanelManager::GetInstance()->panels();
215 for (size_t i
= 0; i
< panels
.size(); ++i
) {
216 if (panels
[i
]->GetWebContents() == web_contents
) {
223 case content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED
:
225 for (PanelResourceMap::iterator iter
= resources_
.begin();
226 iter
!= resources_
.end(); ++iter
) {
227 Panel
* panel
= iter
->first
;
228 WebContents
* panel_contents
= panel
->GetWebContents();
229 if (!panel_contents
|| panel_contents
== web_contents
) {
237 NOTREACHED() << "Unexpected notificiation.";
242 } // namespace task_manager