OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/background/background_application_list_model.h" | 5 #include "chrome/browser/background/background_application_list_model.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <set> | 8 #include <set> |
9 | 9 |
10 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
11 #include "base/utf_string_conversions.h" | 11 #include "base/utf_string_conversions.h" |
12 #include "chrome/app/chrome_command_ids.h" | 12 #include "chrome/app/chrome_command_ids.h" |
13 #include "chrome/browser/background/background_mode_manager.h" | 13 #include "chrome/browser/background/background_mode_manager.h" |
14 #include "chrome/browser/background/background_contents_service.h" | |
15 #include "chrome/browser/background/background_contents_service_factory.h" | |
14 #include "chrome/browser/browser_process.h" | 16 #include "chrome/browser/browser_process.h" |
15 #include "chrome/browser/extensions/extension_prefs.h" | 17 #include "chrome/browser/extensions/extension_prefs.h" |
16 #include "chrome/browser/extensions/extension_service.h" | 18 #include "chrome/browser/extensions/extension_service.h" |
17 #include "chrome/browser/extensions/image_loading_tracker.h" | 19 #include "chrome/browser/extensions/image_loading_tracker.h" |
18 #include "chrome/browser/profiles/profile.h" | 20 #include "chrome/browser/profiles/profile.h" |
19 #include "chrome/common/chrome_notification_types.h" | 21 #include "chrome/common/chrome_notification_types.h" |
20 #include "chrome/common/extensions/extension.h" | 22 #include "chrome/common/extensions/extension.h" |
21 #include "chrome/common/extensions/extension_icon_set.h" | 23 #include "chrome/common/extensions/extension_icon_set.h" |
22 #include "chrome/common/extensions/extension_resource.h" | 24 #include "chrome/common/extensions/extension_resource.h" |
23 #include "content/public/browser/notification_details.h" | 25 #include "content/public/browser/notification_details.h" |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
72 | 74 |
73 namespace { | 75 namespace { |
74 void GetServiceApplications(ExtensionService* service, | 76 void GetServiceApplications(ExtensionService* service, |
75 ExtensionList* applications_result) { | 77 ExtensionList* applications_result) { |
76 const ExtensionSet* extensions = service->extensions(); | 78 const ExtensionSet* extensions = service->extensions(); |
77 | 79 |
78 for (ExtensionSet::const_iterator cursor = extensions->begin(); | 80 for (ExtensionSet::const_iterator cursor = extensions->begin(); |
79 cursor != extensions->end(); | 81 cursor != extensions->end(); |
80 ++cursor) { | 82 ++cursor) { |
81 const Extension* extension = *cursor; | 83 const Extension* extension = *cursor; |
82 if (BackgroundApplicationListModel::IsBackgroundApp(*extension)) | 84 if (BackgroundApplicationListModel::IsBackgroundApp(*extension, |
85 service->profile())) { | |
83 applications_result->push_back(extension); | 86 applications_result->push_back(extension); |
87 } | |
84 } | 88 } |
85 | 89 |
86 // Walk the list of terminated extensions also (just because an extension | 90 // Walk the list of terminated extensions also (just because an extension |
87 // crashed doesn't mean we should ignore it). | 91 // crashed doesn't mean we should ignore it). |
88 extensions = service->terminated_extensions(); | 92 extensions = service->terminated_extensions(); |
89 for (ExtensionSet::const_iterator cursor = extensions->begin(); | 93 for (ExtensionSet::const_iterator cursor = extensions->begin(); |
90 cursor != extensions->end(); | 94 cursor != extensions->end(); |
91 ++cursor) { | 95 ++cursor) { |
92 const Extension* extension = *cursor; | 96 const Extension* extension = *cursor; |
93 if (BackgroundApplicationListModel::IsBackgroundApp(*extension)) | 97 if (BackgroundApplicationListModel::IsBackgroundApp(*extension, |
98 service->profile())) { | |
94 applications_result->push_back(extension); | 99 applications_result->push_back(extension); |
100 } | |
95 } | 101 } |
96 | 102 |
97 std::string locale = g_browser_process->GetApplicationLocale(); | 103 std::string locale = g_browser_process->GetApplicationLocale(); |
98 icu::Locale loc(locale.c_str()); | 104 icu::Locale loc(locale.c_str()); |
99 UErrorCode error = U_ZERO_ERROR; | 105 UErrorCode error = U_ZERO_ERROR; |
100 scoped_ptr<icu::Collator> collator(icu::Collator::createInstance(loc, error)); | 106 scoped_ptr<icu::Collator> collator(icu::Collator::createInstance(loc, error)); |
101 std::sort(applications_result->begin(), applications_result->end(), | 107 std::sort(applications_result->begin(), applications_result->end(), |
102 ExtensionNameComparator(collator.get())); | 108 ExtensionNameComparator(collator.get())); |
103 } | 109 } |
104 | 110 |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
160 content::Source<Profile>(profile)); | 166 content::Source<Profile>(profile)); |
161 registrar_.Add(this, | 167 registrar_.Add(this, |
162 chrome::NOTIFICATION_EXTENSION_UNLOADED, | 168 chrome::NOTIFICATION_EXTENSION_UNLOADED, |
163 content::Source<Profile>(profile)); | 169 content::Source<Profile>(profile)); |
164 registrar_.Add(this, | 170 registrar_.Add(this, |
165 chrome::NOTIFICATION_EXTENSIONS_READY, | 171 chrome::NOTIFICATION_EXTENSIONS_READY, |
166 content::Source<Profile>(profile)); | 172 content::Source<Profile>(profile)); |
167 registrar_.Add(this, | 173 registrar_.Add(this, |
168 chrome::NOTIFICATION_EXTENSION_PERMISSIONS_UPDATED, | 174 chrome::NOTIFICATION_EXTENSION_PERMISSIONS_UPDATED, |
169 content::Source<Profile>(profile)); | 175 content::Source<Profile>(profile)); |
176 registrar_.Add(this, | |
177 chrome::NOTIFICATION_BACKGROUND_CONTENTS_SERVICE_CHANGED, | |
178 content::Source<Profile>(profile)); | |
170 ExtensionService* service = profile->GetExtensionService(); | 179 ExtensionService* service = profile->GetExtensionService(); |
171 if (service && service->is_ready()) | 180 if (service && service->is_ready()) |
172 Update(); | 181 Update(); |
173 } | 182 } |
174 | 183 |
175 void BackgroundApplicationListModel::AddObserver(Observer* observer) { | 184 void BackgroundApplicationListModel::AddObserver(Observer* observer) { |
176 observers_.AddObserver(observer); | 185 observers_.AddObserver(observer); |
177 } | 186 } |
178 | 187 |
179 void BackgroundApplicationListModel::AssociateApplicationData( | 188 void BackgroundApplicationListModel::AssociateApplicationData( |
180 const Extension* extension) { | 189 const Extension* extension) { |
181 DCHECK(IsBackgroundApp(*extension)); | 190 DCHECK(IsBackgroundApp(*extension, profile_)); |
182 Application* application = FindApplication(extension); | 191 Application* application = FindApplication(extension); |
183 if (!application) { | 192 if (!application) { |
184 // App position is used as a dynamic command and so must be less than any | 193 // App position is used as a dynamic command and so must be less than any |
185 // predefined command id. | 194 // predefined command id. |
186 if (applications_.size() >= IDC_MinimumLabelValue) { | 195 if (applications_.size() >= IDC_MinimumLabelValue) { |
187 LOG(ERROR) << "Background application limit of " << IDC_MinimumLabelValue | 196 LOG(ERROR) << "Background application limit of " << IDC_MinimumLabelValue |
188 << " exceeded. Ignoring."; | 197 << " exceeded. Ignoring."; |
189 return; | 198 return; |
190 } | 199 } |
191 application = new Application(this, extension); | 200 application = new Application(this, extension); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
243 ++cursor, ++position) { | 252 ++cursor, ++position) { |
244 if (id == cursor->get()->id()) | 253 if (id == cursor->get()->id()) |
245 return position; | 254 return position; |
246 } | 255 } |
247 NOTREACHED(); | 256 NOTREACHED(); |
248 return -1; | 257 return -1; |
249 } | 258 } |
250 | 259 |
251 // static | 260 // static |
252 bool BackgroundApplicationListModel::IsBackgroundApp( | 261 bool BackgroundApplicationListModel::IsBackgroundApp( |
253 const Extension& extension) { | 262 const Extension& extension, Profile* profile) { |
254 return extension.HasAPIPermission(ExtensionAPIPermission::kBackground); | 263 // An extension is a "background app" if it has the "background API" |
264 // permission, and meets one of the following criteria: | |
265 // 1) It is an extension (not a hosted app). | |
266 // 2) It is a hosted app, and has a background contents registered or in the | |
267 // manifest. | |
268 | |
269 // Not a background app if we don't have the background permission. | |
270 if (!extension.HasAPIPermission(ExtensionAPIPermission::kBackground)) | |
271 return false; | |
272 | |
273 // Extensions with background permission are always treated as background | |
Mihai Parparita -not on Chrome
2012/05/03 00:54:11
Nit: "Extensions and packaged apps"
Andrew T Wilson (Slow)
2012/05/03 07:42:56
Done.
| |
274 // apps. | |
275 if (!extension.is_hosted_app()) | |
276 return true; | |
277 | |
278 // Hosted apps with manifest-provided background pages are background apps. | |
279 if (extension.has_background_page()) | |
280 return true; | |
281 | |
282 BackgroundContentsService* service = | |
283 BackgroundContentsServiceFactory::GetForProfile(profile); | |
284 string16 app_id = ASCIIToUTF16(extension.id()); | |
285 // If we have an active or registered background contents for this app, then | |
286 // it's a background app. This covers the cases where the app has created its | |
287 // background contents, but it hasn't navigated yet, or the background | |
288 // contents crashed and hasn't yet been restarted - in both cases we still | |
289 // want to treat the app as a background app. | |
290 if (service->GetAppBackgroundContents(app_id) || | |
291 service->HasRegisteredBackgroundContents(app_id)) { | |
292 return true; | |
293 } | |
294 | |
295 // Doesn't meet our criteria, so it's not a background app. | |
296 return false; | |
255 } | 297 } |
256 | 298 |
257 void BackgroundApplicationListModel::Observe( | 299 void BackgroundApplicationListModel::Observe( |
258 int type, | 300 int type, |
259 const content::NotificationSource& source, | 301 const content::NotificationSource& source, |
260 const content::NotificationDetails& details) { | 302 const content::NotificationDetails& details) { |
261 if (type == chrome::NOTIFICATION_EXTENSIONS_READY) { | 303 if (type == chrome::NOTIFICATION_EXTENSIONS_READY) { |
262 Update(); | 304 Update(); |
263 return; | 305 return; |
264 } | 306 } |
265 ExtensionService* service = profile_->GetExtensionService(); | 307 ExtensionService* service = profile_->GetExtensionService(); |
266 if (!service || !service->is_ready()) | 308 if (!service || !service->is_ready()) |
267 return; | 309 return; |
268 | 310 |
269 switch (type) { | 311 switch (type) { |
270 case chrome::NOTIFICATION_EXTENSION_LOADED: | 312 case chrome::NOTIFICATION_EXTENSION_LOADED: |
271 OnExtensionLoaded(content::Details<Extension>(details).ptr()); | 313 OnExtensionLoaded(content::Details<Extension>(details).ptr()); |
272 break; | 314 break; |
273 case chrome::NOTIFICATION_EXTENSION_UNLOADED: | 315 case chrome::NOTIFICATION_EXTENSION_UNLOADED: |
274 OnExtensionUnloaded( | 316 OnExtensionUnloaded( |
275 content::Details<UnloadedExtensionInfo>(details)->extension); | 317 content::Details<UnloadedExtensionInfo>(details)->extension); |
276 break; | 318 break; |
277 case chrome::NOTIFICATION_EXTENSION_PERMISSIONS_UPDATED: | 319 case chrome::NOTIFICATION_EXTENSION_PERMISSIONS_UPDATED: |
278 OnExtensionPermissionsUpdated( | 320 OnExtensionPermissionsUpdated( |
279 content::Details<UpdatedExtensionPermissionsInfo>(details)->extension, | 321 content::Details<UpdatedExtensionPermissionsInfo>(details)->extension, |
280 content::Details<UpdatedExtensionPermissionsInfo>(details)->reason, | 322 content::Details<UpdatedExtensionPermissionsInfo>(details)->reason, |
281 content::Details<UpdatedExtensionPermissionsInfo>(details)-> | 323 content::Details<UpdatedExtensionPermissionsInfo>(details)-> |
282 permissions); | 324 permissions); |
283 break; | 325 break; |
326 case chrome::NOTIFICATION_BACKGROUND_CONTENTS_SERVICE_CHANGED: | |
327 Update(); | |
328 break; | |
284 default: | 329 default: |
285 NOTREACHED() << "Received unexpected notification"; | 330 NOTREACHED() << "Received unexpected notification"; |
286 } | 331 } |
287 } | 332 } |
288 | 333 |
289 void BackgroundApplicationListModel::SendApplicationDataChangedNotifications( | 334 void BackgroundApplicationListModel::SendApplicationDataChangedNotifications( |
290 const Extension* extension) { | 335 const Extension* extension) { |
291 FOR_EACH_OBSERVER(Observer, observers_, OnApplicationDataChanged(extension, | 336 FOR_EACH_OBSERVER(Observer, observers_, OnApplicationDataChanged(extension, |
292 profile_)); | 337 profile_)); |
293 } | 338 } |
294 | 339 |
295 void BackgroundApplicationListModel::OnExtensionLoaded( | 340 void BackgroundApplicationListModel::OnExtensionLoaded( |
296 const Extension* extension) { | 341 const Extension* extension) { |
297 // We only care about extensions that are background applications | 342 // We only care about extensions that are background applications |
298 if (!IsBackgroundApp(*extension)) | 343 if (!IsBackgroundApp(*extension, profile_)) |
299 return; | 344 return; |
300 AssociateApplicationData(extension); | 345 AssociateApplicationData(extension); |
301 } | 346 } |
302 | 347 |
303 void BackgroundApplicationListModel::OnExtensionUnloaded( | 348 void BackgroundApplicationListModel::OnExtensionUnloaded( |
304 const Extension* extension) { | 349 const Extension* extension) { |
305 if (!IsBackgroundApp(*extension)) | 350 if (!IsBackgroundApp(*extension, profile_)) |
306 return; | 351 return; |
307 Update(); | 352 Update(); |
308 DissociateApplicationData(extension); | 353 DissociateApplicationData(extension); |
309 } | 354 } |
310 | 355 |
311 void BackgroundApplicationListModel::OnExtensionPermissionsUpdated( | 356 void BackgroundApplicationListModel::OnExtensionPermissionsUpdated( |
312 const Extension* extension, | 357 const Extension* extension, |
313 UpdatedExtensionPermissionsInfo::Reason reason, | 358 UpdatedExtensionPermissionsInfo::Reason reason, |
314 const ExtensionPermissionSet* permissions) { | 359 const ExtensionPermissionSet* permissions) { |
315 if (permissions->HasAPIPermission(ExtensionAPIPermission::kBackground)) { | 360 if (permissions->HasAPIPermission(ExtensionAPIPermission::kBackground)) { |
316 switch (reason) { | 361 switch (reason) { |
317 case UpdatedExtensionPermissionsInfo::ADDED: | 362 case UpdatedExtensionPermissionsInfo::ADDED: |
318 DCHECK(IsBackgroundApp(*extension)); | 363 DCHECK(IsBackgroundApp(*extension, profile_)); |
319 OnExtensionLoaded(extension); | 364 OnExtensionLoaded(extension); |
320 break; | 365 break; |
321 case UpdatedExtensionPermissionsInfo::REMOVED: | 366 case UpdatedExtensionPermissionsInfo::REMOVED: |
322 DCHECK(!IsBackgroundApp(*extension)); | 367 DCHECK(!IsBackgroundApp(*extension, profile_)); |
323 Update(); | 368 Update(); |
324 DissociateApplicationData(extension); | 369 DissociateApplicationData(extension); |
325 break; | 370 break; |
326 default: | 371 default: |
327 NOTREACHED(); | 372 NOTREACHED(); |
328 } | 373 } |
329 } | 374 } |
330 } | 375 } |
331 | 376 |
332 void BackgroundApplicationListModel::RemoveObserver(Observer* observer) { | 377 void BackgroundApplicationListModel::RemoveObserver(Observer* observer) { |
(...skipping 18 matching lines...) Expand all Loading... | |
351 (*old_cursor)->name() == (*new_cursor)->name() && | 396 (*old_cursor)->name() == (*new_cursor)->name() && |
352 (*old_cursor)->id() == (*new_cursor)->id()) { | 397 (*old_cursor)->id() == (*new_cursor)->id()) { |
353 ++old_cursor; | 398 ++old_cursor; |
354 ++new_cursor; | 399 ++new_cursor; |
355 } | 400 } |
356 if (old_cursor != extensions_.end() || new_cursor != extensions.end()) { | 401 if (old_cursor != extensions_.end() || new_cursor != extensions.end()) { |
357 extensions_ = extensions; | 402 extensions_ = extensions; |
358 FOR_EACH_OBSERVER(Observer, observers_, OnApplicationListChanged(profile_)); | 403 FOR_EACH_OBSERVER(Observer, observers_, OnApplicationListChanged(profile_)); |
359 } | 404 } |
360 } | 405 } |
OLD | NEW |