1 // Copyright (c) 2012 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/notification_resource_provider.h"
7 #include "base/strings/string16.h"
8 #include "chrome/browser/browser_process.h"
9 #include "chrome/browser/chrome_notification_types.h"
10 #include "chrome/browser/devtools/devtools_window.h"
11 #include "chrome/browser/notifications/balloon_host.h"
12 #include "chrome/browser/notifications/balloon_notification_ui_manager.h"
13 #include "chrome/browser/task_manager/task_manager.h"
14 #include "content/public/browser/notification_service.h"
15 #include "content/public/browser/render_process_host.h"
16 #include "content/public/browser/web_contents.h"
17 #include "grit/generated_resources.h"
18 #include "grit/theme_resources.h"
19 #include "ui/base/l10n/l10n_util.h"
20 #include "ui/base/resource/resource_bundle.h"
21 #include "ui/gfx/image/image_skia.h"
23 namespace task_manager
{
25 class NotificationResource
: public Resource
{
27 explicit NotificationResource(BalloonHost
* balloon_host
);
28 virtual ~NotificationResource();
31 virtual base::string16
GetTitle() const OVERRIDE
;
32 virtual base::string16
GetProfileName() const OVERRIDE
;
33 virtual gfx::ImageSkia
GetIcon() const OVERRIDE
;
34 virtual base::ProcessHandle
GetProcess() const OVERRIDE
;
35 virtual int GetUniqueChildProcessId() const OVERRIDE
;
36 virtual Type
GetType() const OVERRIDE
;
37 virtual bool CanInspect() const OVERRIDE
;
38 virtual void Inspect() const OVERRIDE
;
39 virtual bool SupportNetworkUsage() const OVERRIDE
;
40 virtual void SetSupportNetworkUsage() OVERRIDE
{ }
43 // The icon painted for notifications. .
44 static gfx::ImageSkia
* default_icon_
;
46 // Non-owned pointer to the balloon host.
47 BalloonHost
* balloon_host_
;
49 // Cached data about the balloon host.
50 base::ProcessHandle process_handle_
;
52 int unique_process_id_
;
53 base::string16 title_
;
55 DISALLOW_COPY_AND_ASSIGN(NotificationResource
);
58 gfx::ImageSkia
* NotificationResource::default_icon_
= NULL
;
60 NotificationResource::NotificationResource(BalloonHost
* balloon_host
)
61 : balloon_host_(balloon_host
) {
63 ResourceBundle
& rb
= ResourceBundle::GetSharedInstance();
64 default_icon_
= rb
.GetImageSkiaNamed(IDR_PLUGINS_FAVICON
);
67 balloon_host_
->web_contents()->GetRenderProcessHost()->GetHandle();
69 balloon_host_
->web_contents()->GetRenderProcessHost()->GetID();
70 pid_
= base::GetProcId(process_handle_
);
71 title_
= l10n_util::GetStringFUTF16(IDS_TASK_MANAGER_NOTIFICATION_PREFIX
,
72 balloon_host_
->GetSource());
75 NotificationResource::~NotificationResource() {
78 base::string16
NotificationResource::GetTitle() const {
82 base::string16
NotificationResource::GetProfileName() const {
83 return base::string16();
86 gfx::ImageSkia
NotificationResource::GetIcon() const {
87 return *default_icon_
;
90 base::ProcessHandle
NotificationResource::GetProcess() const {
91 return process_handle_
;
94 int NotificationResource::GetUniqueChildProcessId() const {
95 return unique_process_id_
;
98 Resource::Type
NotificationResource::GetType() const {
102 bool NotificationResource::CanInspect() const {
106 void NotificationResource::Inspect() const {
107 DevToolsWindow::OpenDevToolsWindow(
108 balloon_host_
->web_contents()->GetRenderViewHost());
111 bool NotificationResource::SupportNetworkUsage() const {
115 ////////////////////////////////////////////////////////////////////////////////
116 // NotificationResourceProvider class
117 ////////////////////////////////////////////////////////////////////////////////
120 NotificationResourceProvider
*
121 NotificationResourceProvider::Create(TaskManager
* task_manager
) {
122 return new NotificationResourceProvider(task_manager
);
125 NotificationResourceProvider::
126 NotificationResourceProvider(TaskManager
* task_manager
)
127 : task_manager_(task_manager
),
131 NotificationResourceProvider::~NotificationResourceProvider() {
134 Resource
* NotificationResourceProvider::GetResource(
138 // TODO(johnnyg): provide resources by pid if necessary.
142 void NotificationResourceProvider::StartUpdating() {
143 // MessageCenter does not use Balloons.
144 if (NotificationUIManager::DelegatesToMessageCenter())
150 // Add all the existing BalloonHosts.
151 BalloonNotificationUIManager
* balloon_manager
=
152 static_cast<BalloonNotificationUIManager
*>(
153 g_browser_process
->notification_ui_manager());
154 BalloonCollection
* collection
= balloon_manager
->balloon_collection();
155 const BalloonCollection::Balloons
& balloons
=
156 collection
->GetActiveBalloons();
157 for (BalloonCollection::Balloons::const_iterator it
= balloons
.begin();
158 it
!= balloons
.end(); ++it
) {
159 BalloonHost
* balloon_host
= (*it
)->balloon_view()->GetHost();
161 AddToTaskManager(balloon_host
);
163 // Register for notifications about extension process changes.
164 registrar_
.Add(this, chrome::NOTIFICATION_NOTIFY_BALLOON_CONNECTED
,
165 content::NotificationService::AllSources());
166 registrar_
.Add(this, chrome::NOTIFICATION_NOTIFY_BALLOON_DISCONNECTED
,
167 content::NotificationService::AllSources());
170 void NotificationResourceProvider::StopUpdating() {
171 // MessageCenter does not use Balloons.
172 if (NotificationUIManager::DelegatesToMessageCenter())
178 // Unregister for notifications about extension process changes.
179 registrar_
.Remove(this, chrome::NOTIFICATION_NOTIFY_BALLOON_CONNECTED
,
180 content::NotificationService::AllSources());
181 registrar_
.Remove(this, chrome::NOTIFICATION_NOTIFY_BALLOON_DISCONNECTED
,
182 content::NotificationService::AllSources());
184 // Delete all the resources.
185 STLDeleteContainerPairSecondPointers(resources_
.begin(), resources_
.end());
189 void NotificationResourceProvider::Observe(
191 const content::NotificationSource
& source
,
192 const content::NotificationDetails
& details
) {
194 case chrome::NOTIFICATION_NOTIFY_BALLOON_CONNECTED
:
195 AddToTaskManager(content::Source
<BalloonHost
>(source
).ptr());
197 case chrome::NOTIFICATION_NOTIFY_BALLOON_DISCONNECTED
:
198 RemoveFromTaskManager(content::Source
<BalloonHost
>(source
).ptr());
201 NOTREACHED() << "Unexpected notification.";
206 void NotificationResourceProvider::AddToTaskManager(
207 BalloonHost
* balloon_host
) {
208 NotificationResource
* resource
= new NotificationResource(balloon_host
);
209 DCHECK(resources_
.find(balloon_host
) == resources_
.end());
210 resources_
[balloon_host
] = resource
;
211 task_manager_
->AddResource(resource
);
214 void NotificationResourceProvider::RemoveFromTaskManager(
215 BalloonHost
* balloon_host
) {
218 std::map
<BalloonHost
*, NotificationResource
*>::iterator iter
=
219 resources_
.find(balloon_host
);
220 if (iter
== resources_
.end())
223 // Remove the resource from the Task Manager.
224 NotificationResource
* resource
= iter
->second
;
225 task_manager_
->RemoveResource(resource
);
227 // Remove it from the map.
228 resources_
.erase(iter
);
230 // Finally, delete the resource.
234 } // namespace task_manager