| 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;
|
|
|