Index: chrome/browser/background/background_application_list_model.cc |
diff --git a/chrome/browser/background/background_application_list_model.cc b/chrome/browser/background/background_application_list_model.cc |
index dfb4a2d9792d33eb4d2795acf01aeab632b7767e..a414cf14cee9f2de830bf70660756c91fff1a2be 100644 |
--- a/chrome/browser/background/background_application_list_model.cc |
+++ b/chrome/browser/background/background_application_list_model.cc |
@@ -11,6 +11,8 @@ |
#include "base/utf_string_conversions.h" |
#include "chrome/app/chrome_command_ids.h" |
#include "chrome/browser/background/background_mode_manager.h" |
+#include "chrome/browser/background/background_contents_service.h" |
+#include "chrome/browser/background/background_contents_service_factory.h" |
#include "chrome/browser/browser_process.h" |
#include "chrome/browser/extensions/extension_prefs.h" |
#include "chrome/browser/extensions/extension_service.h" |
@@ -79,8 +81,10 @@ void GetServiceApplications(ExtensionService* service, |
cursor != extensions->end(); |
++cursor) { |
const Extension* extension = *cursor; |
- if (BackgroundApplicationListModel::IsBackgroundApp(*extension)) |
+ if (BackgroundApplicationListModel::IsBackgroundApp(*extension, |
+ service->profile())) { |
applications_result->push_back(extension); |
+ } |
} |
// Walk the list of terminated extensions also (just because an extension |
@@ -90,8 +94,10 @@ void GetServiceApplications(ExtensionService* service, |
cursor != extensions->end(); |
++cursor) { |
const Extension* extension = *cursor; |
- if (BackgroundApplicationListModel::IsBackgroundApp(*extension)) |
+ if (BackgroundApplicationListModel::IsBackgroundApp(*extension, |
+ service->profile())) { |
applications_result->push_back(extension); |
+ } |
} |
std::string locale = g_browser_process->GetApplicationLocale(); |
@@ -167,6 +173,9 @@ BackgroundApplicationListModel::BackgroundApplicationListModel(Profile* profile) |
registrar_.Add(this, |
chrome::NOTIFICATION_EXTENSION_PERMISSIONS_UPDATED, |
content::Source<Profile>(profile)); |
+ registrar_.Add(this, |
+ chrome::NOTIFICATION_BACKGROUND_CONTENTS_SERVICE_CHANGED, |
+ content::Source<Profile>(profile)); |
ExtensionService* service = profile->GetExtensionService(); |
if (service && service->is_ready()) |
Update(); |
@@ -178,7 +187,7 @@ void BackgroundApplicationListModel::AddObserver(Observer* observer) { |
void BackgroundApplicationListModel::AssociateApplicationData( |
const Extension* extension) { |
- DCHECK(IsBackgroundApp(*extension)); |
+ DCHECK(IsBackgroundApp(*extension, profile_)); |
Application* application = FindApplication(extension); |
if (!application) { |
// App position is used as a dynamic command and so must be less than any |
@@ -250,8 +259,41 @@ int BackgroundApplicationListModel::GetPosition( |
// static |
bool BackgroundApplicationListModel::IsBackgroundApp( |
- const Extension& extension) { |
- return extension.HasAPIPermission(ExtensionAPIPermission::kBackground); |
+ const Extension& extension, Profile* profile) { |
+ // An extension is a "background app" if it has the "background API" |
+ // permission, and meets one of the following criteria: |
+ // 1) It is an extension (not a hosted app). |
+ // 2) It is a hosted app, and has a background contents registered or in the |
+ // manifest. |
+ |
+ // Not a background app if we don't have the background permission. |
+ if (!extension.HasAPIPermission(ExtensionAPIPermission::kBackground)) |
+ return false; |
+ |
+ // Extensions and packaged apps with background permission are always treated |
+ // as background apps. |
+ if (!extension.is_hosted_app()) |
+ return true; |
+ |
+ // Hosted apps with manifest-provided background pages are background apps. |
+ if (extension.has_background_page()) |
+ return true; |
+ |
+ BackgroundContentsService* service = |
+ BackgroundContentsServiceFactory::GetForProfile(profile); |
+ string16 app_id = ASCIIToUTF16(extension.id()); |
+ // If we have an active or registered background contents for this app, then |
+ // it's a background app. This covers the cases where the app has created its |
+ // background contents, but it hasn't navigated yet, or the background |
+ // contents crashed and hasn't yet been restarted - in both cases we still |
+ // want to treat the app as a background app. |
+ if (service->GetAppBackgroundContents(app_id) || |
+ service->HasRegisteredBackgroundContents(app_id)) { |
+ return true; |
+ } |
+ |
+ // Doesn't meet our criteria, so it's not a background app. |
+ return false; |
} |
void BackgroundApplicationListModel::Observe( |
@@ -281,6 +323,9 @@ void BackgroundApplicationListModel::Observe( |
content::Details<UpdatedExtensionPermissionsInfo>(details)-> |
permissions); |
break; |
+ case chrome::NOTIFICATION_BACKGROUND_CONTENTS_SERVICE_CHANGED: |
+ Update(); |
+ break; |
default: |
NOTREACHED() << "Received unexpected notification"; |
} |
@@ -295,14 +340,14 @@ void BackgroundApplicationListModel::SendApplicationDataChangedNotifications( |
void BackgroundApplicationListModel::OnExtensionLoaded( |
const Extension* extension) { |
// We only care about extensions that are background applications |
- if (!IsBackgroundApp(*extension)) |
+ if (!IsBackgroundApp(*extension, profile_)) |
return; |
AssociateApplicationData(extension); |
} |
void BackgroundApplicationListModel::OnExtensionUnloaded( |
const Extension* extension) { |
- if (!IsBackgroundApp(*extension)) |
+ if (!IsBackgroundApp(*extension, profile_)) |
return; |
Update(); |
DissociateApplicationData(extension); |
@@ -315,11 +360,11 @@ void BackgroundApplicationListModel::OnExtensionPermissionsUpdated( |
if (permissions->HasAPIPermission(ExtensionAPIPermission::kBackground)) { |
switch (reason) { |
case UpdatedExtensionPermissionsInfo::ADDED: |
- DCHECK(IsBackgroundApp(*extension)); |
+ DCHECK(IsBackgroundApp(*extension, profile_)); |
OnExtensionLoaded(extension); |
break; |
case UpdatedExtensionPermissionsInfo::REMOVED: |
- DCHECK(!IsBackgroundApp(*extension)); |
+ DCHECK(!IsBackgroundApp(*extension, profile_)); |
Update(); |
DissociateApplicationData(extension); |
break; |