Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(156)

Side by Side Diff: chrome/browser/task_manager/task_manager_background_resource_provider.cc

Issue 15196003: Create task_manager namespace and wrap classes related to TaskManager with it. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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/task_manager_background_resource_provider. h"
6
7 #include "base/i18n/rtl.h"
8 #include "base/string16.h"
9 #include "base/utf_string_conversions.h"
10 #include "chrome/browser/background/background_contents_service.h"
11 #include "chrome/browser/background/background_contents_service_factory.h"
12 #include "chrome/browser/browser_process.h"
13 #include "chrome/browser/extensions/extension_service.h"
14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/browser/profiles/profile_manager.h"
16 #include "chrome/browser/tab_contents/background_contents.h"
17 #include "chrome/browser/task_manager/task_manager_render_resource.h"
18 #include "chrome/common/chrome_notification_types.h"
19 #include "chrome/common/extensions/extension.h"
20 #include "content/public/browser/notification_service.h"
21 #include "content/public/browser/render_process_host.h"
22 #include "content/public/browser/render_view_host.h"
23 #include "content/public/browser/web_contents.h"
24 #include "grit/generated_resources.h"
25 #include "grit/theme_resources.h"
26 #include "ui/base/l10n/l10n_util.h"
27 #include "ui/base/resource/resource_bundle.h"
28 #include "ui/gfx/image/image_skia.h"
29
30 using content::RenderProcessHost;
31 using content::RenderViewHost;
32 using content::WebContents;
33 using extensions::Extension;
34
35 class TaskManagerBackgroundContentsResource
36 : public TaskManagerRendererResource {
37 public:
38 TaskManagerBackgroundContentsResource(
39 BackgroundContents* background_contents,
40 const string16& application_name);
41 virtual ~TaskManagerBackgroundContentsResource();
42
43 // TaskManager::Resource methods:
44 virtual string16 GetTitle() const OVERRIDE;
45 virtual string16 GetProfileName() const OVERRIDE;
46 virtual gfx::ImageSkia GetIcon() const OVERRIDE;
47 virtual bool IsBackground() const OVERRIDE;
48
49 const string16& application_name() const { return application_name_; }
50 private:
51 BackgroundContents* background_contents_;
52
53 string16 application_name_;
54
55 // The icon painted for BackgroundContents.
56 // TODO(atwilson): Use the favicon when there's a way to get the favicon for
57 // BackgroundContents.
58 static gfx::ImageSkia* default_icon_;
59
60 DISALLOW_COPY_AND_ASSIGN(TaskManagerBackgroundContentsResource);
61 };
62
63 gfx::ImageSkia* TaskManagerBackgroundContentsResource::default_icon_ = NULL;
64
65 // TODO(atwilson): http://crbug.com/116893
66 // HACK: if the process handle is invalid, we use the current process's handle.
67 // This preserves old behavior but is incorrect, and should be fixed.
68 TaskManagerBackgroundContentsResource::TaskManagerBackgroundContentsResource(
69 BackgroundContents* background_contents,
70 const string16& application_name)
71 : TaskManagerRendererResource(
72 background_contents->web_contents()->GetRenderProcessHost()->
73 GetHandle() ?
74 background_contents->web_contents()->GetRenderProcessHost()->
75 GetHandle() :
76 base::Process::Current().handle(),
77 background_contents->web_contents()->GetRenderViewHost()),
78 background_contents_(background_contents),
79 application_name_(application_name) {
80 // Just use the same icon that other extension resources do.
81 // TODO(atwilson): Use the favicon when that's available.
82 if (!default_icon_) {
83 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
84 default_icon_ = rb.GetImageSkiaNamed(IDR_PLUGINS_FAVICON);
85 }
86 // Ensure that the string has the appropriate direction markers (see comment
87 // in TaskManagerTabContentsResource::GetTitle()).
88 base::i18n::AdjustStringForLocaleDirection(&application_name_);
89 }
90
91 TaskManagerBackgroundContentsResource::~TaskManagerBackgroundContentsResource(
92 ) {
93 }
94
95 string16 TaskManagerBackgroundContentsResource::GetTitle() const {
96 string16 title = application_name_;
97
98 if (title.empty()) {
99 // No title (can't locate the parent app for some reason) so just display
100 // the URL (properly forced to be LTR).
101 title = base::i18n::GetDisplayStringInLTRDirectionality(
102 UTF8ToUTF16(background_contents_->GetURL().spec()));
103 }
104 return l10n_util::GetStringFUTF16(IDS_TASK_MANAGER_BACKGROUND_PREFIX, title);
105 }
106
107 string16 TaskManagerBackgroundContentsResource::GetProfileName() const {
108 return string16();
109 }
110
111 gfx::ImageSkia TaskManagerBackgroundContentsResource::GetIcon() const {
112 return *default_icon_;
113 }
114
115 bool TaskManagerBackgroundContentsResource::IsBackground() const {
116 return true;
117 }
118
119 ////////////////////////////////////////////////////////////////////////////////
120 // TaskManagerBackgroundContentsResourceProvider class
121 ////////////////////////////////////////////////////////////////////////////////
122
123 TaskManagerBackgroundContentsResourceProvider::
124 TaskManagerBackgroundContentsResourceProvider(TaskManager* task_manager)
125 : updating_(false),
126 task_manager_(task_manager) {
127 }
128
129 TaskManagerBackgroundContentsResourceProvider::
130 ~TaskManagerBackgroundContentsResourceProvider() {
131 }
132
133 TaskManager::Resource*
134 TaskManagerBackgroundContentsResourceProvider::GetResource(
135 int origin_pid,
136 int render_process_host_id,
137 int routing_id) {
138 // If an origin PID was specified, the request is from a plugin, not the
139 // render view host process
140 if (origin_pid)
141 return NULL;
142
143 for (Resources::iterator i = resources_.begin(); i != resources_.end(); i++) {
144 WebContents* tab = i->first->web_contents();
145 if (tab->GetRenderProcessHost()->GetID() == render_process_host_id
146 && tab->GetRenderViewHost()->GetRoutingID() == routing_id) {
147 return i->second;
148 }
149 }
150
151 // Can happen if the page went away while a network request was being
152 // performed.
153 return NULL;
154 }
155
156 void TaskManagerBackgroundContentsResourceProvider::StartUpdating() {
157 DCHECK(!updating_);
158 updating_ = true;
159
160 // Add all the existing BackgroundContents from every profile, including
161 // incognito profiles.
162 ProfileManager* profile_manager = g_browser_process->profile_manager();
163 std::vector<Profile*> profiles(profile_manager->GetLoadedProfiles());
164 size_t num_default_profiles = profiles.size();
165 for (size_t i = 0; i < num_default_profiles; ++i) {
166 if (profiles[i]->HasOffTheRecordProfile()) {
167 profiles.push_back(profiles[i]->GetOffTheRecordProfile());
168 }
169 }
170 for (size_t i = 0; i < profiles.size(); ++i) {
171 BackgroundContentsService* background_contents_service =
172 BackgroundContentsServiceFactory::GetForProfile(profiles[i]);
173 std::vector<BackgroundContents*> contents =
174 background_contents_service->GetBackgroundContents();
175 ExtensionService* extension_service = profiles[i]->GetExtensionService();
176 for (std::vector<BackgroundContents*>::iterator iterator = contents.begin();
177 iterator != contents.end(); ++iterator) {
178 string16 application_name;
179 // Lookup the name from the parent extension.
180 if (extension_service) {
181 const string16& application_id =
182 background_contents_service->GetParentApplicationId(*iterator);
183 const Extension* extension = extension_service->GetExtensionById(
184 UTF16ToUTF8(application_id), false);
185 if (extension)
186 application_name = UTF8ToUTF16(extension->name());
187 }
188 Add(*iterator, application_name);
189 }
190 }
191
192 // Then we register for notifications to get new BackgroundContents.
193 registrar_.Add(this, chrome::NOTIFICATION_BACKGROUND_CONTENTS_OPENED,
194 content::NotificationService::AllBrowserContextsAndSources());
195 registrar_.Add(this, chrome::NOTIFICATION_BACKGROUND_CONTENTS_NAVIGATED,
196 content::NotificationService::AllBrowserContextsAndSources());
197 registrar_.Add(this, chrome::NOTIFICATION_BACKGROUND_CONTENTS_DELETED,
198 content::NotificationService::AllBrowserContextsAndSources());
199 }
200
201 void TaskManagerBackgroundContentsResourceProvider::StopUpdating() {
202 DCHECK(updating_);
203 updating_ = false;
204
205 // Unregister for notifications
206 registrar_.Remove(
207 this, chrome::NOTIFICATION_BACKGROUND_CONTENTS_OPENED,
208 content::NotificationService::AllBrowserContextsAndSources());
209 registrar_.Remove(
210 this, chrome::NOTIFICATION_BACKGROUND_CONTENTS_NAVIGATED,
211 content::NotificationService::AllBrowserContextsAndSources());
212 registrar_.Remove(
213 this, chrome::NOTIFICATION_BACKGROUND_CONTENTS_DELETED,
214 content::NotificationService::AllBrowserContextsAndSources());
215
216 // Delete all the resources.
217 STLDeleteContainerPairSecondPointers(resources_.begin(), resources_.end());
218
219 resources_.clear();
220 }
221
222 void TaskManagerBackgroundContentsResourceProvider::AddToTaskManager(
223 BackgroundContents* background_contents,
224 const string16& application_name) {
225 TaskManagerBackgroundContentsResource* resource =
226 new TaskManagerBackgroundContentsResource(background_contents,
227 application_name);
228 resources_[background_contents] = resource;
229 task_manager_->AddResource(resource);
230 }
231
232 void TaskManagerBackgroundContentsResourceProvider::Add(
233 BackgroundContents* contents, const string16& application_name) {
234 if (!updating_)
235 return;
236
237 // TODO(atwilson): http://crbug.com/116893
238 // We should check that the process handle is valid here, but it won't
239 // be in the case of NOTIFICATION_BACKGROUND_CONTENTS_OPENED.
240
241 // Should never add the same BackgroundContents twice.
242 DCHECK(resources_.find(contents) == resources_.end());
243 AddToTaskManager(contents, application_name);
244 }
245
246 void TaskManagerBackgroundContentsResourceProvider::Remove(
247 BackgroundContents* contents) {
248 if (!updating_)
249 return;
250 Resources::iterator iter = resources_.find(contents);
251 DCHECK(iter != resources_.end());
252
253 // Remove the resource from the Task Manager.
254 TaskManagerBackgroundContentsResource* resource = iter->second;
255 task_manager_->RemoveResource(resource);
256 // And from the provider.
257 resources_.erase(iter);
258 // Finally, delete the resource.
259 delete resource;
260 }
261
262 void TaskManagerBackgroundContentsResourceProvider::Observe(
263 int type,
264 const content::NotificationSource& source,
265 const content::NotificationDetails& details) {
266 switch (type) {
267 case chrome::NOTIFICATION_BACKGROUND_CONTENTS_OPENED: {
268 // Get the name from the parent application. If no parent application is
269 // found, just pass an empty string - BackgroundContentsResource::GetTitle
270 // will display the URL instead in this case. This should never happen
271 // except in rare cases when an extension is being unloaded or chrome is
272 // exiting while the task manager is displayed.
273 string16 application_name;
274 ExtensionService* service =
275 content::Source<Profile>(source)->GetExtensionService();
276 if (service) {
277 std::string application_id = UTF16ToUTF8(
278 content::Details<BackgroundContentsOpenedDetails>(details)->
279 application_id);
280 const Extension* extension =
281 service->GetExtensionById(application_id, false);
282 // Extension can be NULL when running unit tests.
283 if (extension)
284 application_name = UTF8ToUTF16(extension->name());
285 }
286 Add(content::Details<BackgroundContentsOpenedDetails>(details)->contents,
287 application_name);
288 // Opening a new BackgroundContents needs to force the display to refresh
289 // (applications may now be considered "background" that weren't before).
290 task_manager_->ModelChanged();
291 break;
292 }
293 case chrome::NOTIFICATION_BACKGROUND_CONTENTS_NAVIGATED: {
294 BackgroundContents* contents =
295 content::Details<BackgroundContents>(details).ptr();
296 // Should never get a NAVIGATED before OPENED.
297 DCHECK(resources_.find(contents) != resources_.end());
298 // Preserve the application name.
299 string16 application_name(
300 resources_.find(contents)->second->application_name());
301 Remove(contents);
302 Add(contents, application_name);
303 break;
304 }
305 case chrome::NOTIFICATION_BACKGROUND_CONTENTS_DELETED:
306 Remove(content::Details<BackgroundContents>(details).ptr());
307 // Closing a BackgroundContents needs to force the display to refresh
308 // (applications may now be considered "foreground" that weren't before).
309 task_manager_->ModelChanged();
310 break;
311 default:
312 NOTREACHED() << "Unexpected notification.";
313 return;
314 }
315 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698