15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/background/background_application_list_model.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <set> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/sha1.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h" 121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/strings/string_number_conversions.h" 13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/app/chrome_command_ids.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/background/background_contents_service.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/background/background_contents_service_factory.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/background/background_mode_manager.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/browser_process.h" 197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_service.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/extensions/extension_constants.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_details.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_source.h" 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_prefs.h" 265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_registry.h" 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_system.h" 285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "extensions/browser/extension_util.h" 296d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "extensions/browser/image_loader.h" 305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "extensions/browser/notification_types.h" 31f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.h" 32c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "extensions/common/extension_icon_set.h" 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "extensions/common/extension_resource.h" 345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/common/extension_set.h" 35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/manifest_handlers/background_info.h" 36c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "extensions/common/manifest_handlers/icons_handler.h" 371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "extensions/common/permissions/permission_set.h" 3846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "extensions/common/permissions/permissions_data.h" 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util_collator.h" 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/image/image.h" 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/image/image_skia.h" 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using extensions::APIPermission; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using extensions::Extension; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using extensions::ExtensionList; 465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using extensions::ExtensionRegistry; 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using extensions::ExtensionSet; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using extensions::PermissionSet; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using extensions::UnloadedExtensionInfo; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using extensions::UpdatedExtensionPermissionsInfo; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ExtensionNameComparator { 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit ExtensionNameComparator(icu::Collator* collator); 55eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch bool operator()(const scoped_refptr<const Extension>& x, 56eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const scoped_refptr<const Extension>& y); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) icu::Collator* collator_; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionNameComparator::ExtensionNameComparator(icu::Collator* collator) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : collator_(collator) { 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 66eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool ExtensionNameComparator::operator()( 67eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const scoped_refptr<const Extension>& x, 68eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const scoped_refptr<const Extension>& y) { 695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return l10n_util::StringComparator<base::string16>(collator_)( 705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::UTF8ToUTF16(x->name()), base::UTF8ToUTF16(y->name())); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Background application representation, private to the 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// BackgroundApplicationListModel class. 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BackgroundApplicationListModel::Application 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : public base::SupportsWeakPtr<Application> { 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Application(BackgroundApplicationListModel* model, 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Extension* an_extension); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~Application(); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Invoked when a request icon is available. 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void OnImageLoaded(const gfx::Image& image); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Uses the FILE thread to request this extension's icon, sized 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // appropriately. 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void RequestIcon(extension_misc::ExtensionIcons size); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Extension* extension_; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<gfx::ImageSkia> icon_; 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BackgroundApplicationListModel* model_; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GetServiceApplications(ExtensionService* service, 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionList* applications_result) { 985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ExtensionRegistry* registry = ExtensionRegistry::Get(service->profile()); 995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const ExtensionSet& enabled_extensions = registry->enabled_extensions(); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (ExtensionSet::const_iterator cursor = enabled_extensions.begin(); 1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) cursor != enabled_extensions.end(); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++cursor) { 1047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const Extension* extension = cursor->get(); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (BackgroundApplicationListModel::IsBackgroundApp(*extension, 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) service->profile())) { 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) applications_result->push_back(extension); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Walk the list of terminated extensions also (just because an extension 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // crashed doesn't mean we should ignore it). 1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const ExtensionSet& terminated_extensions = registry->terminated_extensions(); 1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (ExtensionSet::const_iterator cursor = terminated_extensions.begin(); 1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) cursor != terminated_extensions.end(); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++cursor) { 1177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const Extension* extension = cursor->get(); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (BackgroundApplicationListModel::IsBackgroundApp(*extension, 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) service->profile())) { 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) applications_result->push_back(extension); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string locale = g_browser_process->GetApplicationLocale(); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) icu::Locale loc(locale.c_str()); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UErrorCode error = U_ZERO_ERROR; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<icu::Collator> collator(icu::Collator::createInstance(loc, error)); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::sort(applications_result->begin(), applications_result->end(), 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionNameComparator(collator.get())); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BackgroundApplicationListModel::Observer::OnApplicationDataChanged( 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Extension* extension, Profile* profile) { 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BackgroundApplicationListModel::Observer::OnApplicationListChanged( 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* profile) { 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BackgroundApplicationListModel::Observer::~Observer() { 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BackgroundApplicationListModel::Application::~Application() { 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BackgroundApplicationListModel::Application::Application( 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BackgroundApplicationListModel* model, 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Extension* extension) 1537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) : extension_(extension), model_(model) {} 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BackgroundApplicationListModel::Application::OnImageLoaded( 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const gfx::Image& image) { 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (image.IsEmpty()) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) icon_.reset(image.CopyImageSkia()); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model_->SendApplicationDataChangedNotifications(extension_); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BackgroundApplicationListModel::Application::RequestIcon( 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_misc::ExtensionIcons size) { 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extensions::ExtensionResource resource = 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extensions::IconsInfo::GetIconResource( 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension_, size, ExtensionIconSet::MATCH_BIGGER); 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extensions::ImageLoader::Get(model_->profile_)->LoadImageAsync( 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension_, resource, gfx::Size(size, size), 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&Application::OnImageLoaded, AsWeakPtr())); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BackgroundApplicationListModel::~BackgroundApplicationListModel() { 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) STLDeleteContainerPairSecondPointers(applications_.begin(), 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) applications_.end()); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BackgroundApplicationListModel::BackgroundApplicationListModel(Profile* profile) 179116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch : profile_(profile), 180116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ready_(false) { 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(profile_); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) registrar_.Add(this, 1835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) extensions::NOTIFICATION_EXTENSION_LOADED_DEPRECATED, 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<Profile>(profile)); 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) registrar_.Add(this, 1865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) extensions::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED, 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<Profile>(profile)); 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) registrar_.Add(this, 1895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) extensions::NOTIFICATION_EXTENSIONS_READY_DEPRECATED, 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<Profile>(profile)); 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) registrar_.Add(this, 1925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) extensions::NOTIFICATION_EXTENSION_PERMISSIONS_UPDATED, 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<Profile>(profile)); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) registrar_.Add(this, 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::NOTIFICATION_BACKGROUND_CONTENTS_SERVICE_CHANGED, 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<Profile>(profile)); 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ExtensionService* service = extensions::ExtensionSystem::Get(profile)-> 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension_service(); 199116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (service && service->is_ready()) { 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Update(); 201116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ready_ = true; 202116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BackgroundApplicationListModel::AddObserver(Observer* observer) { 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observers_.AddObserver(observer); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BackgroundApplicationListModel::AssociateApplicationData( 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Extension* extension) { 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(IsBackgroundApp(*extension, profile_)); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Application* application = FindApplication(extension); 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!application) { 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // App position is used as a dynamic command and so must be less than any 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // predefined command id. 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (applications_.size() >= IDC_MinimumLabelValue) { 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Background application limit of " << IDC_MinimumLabelValue 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " exceeded. Ignoring."; 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) application = new Application(this, extension); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) applications_[extension->id()] = application; 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Update(); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) application->RequestIcon(extension_misc::EXTENSION_ICON_BITTY); 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BackgroundApplicationListModel::DissociateApplicationData( 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Extension* extension) { 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ApplicationMap::iterator found = applications_.find(extension->id()); 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (found != applications_.end()) { 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete found->second; 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) applications_.erase(found); 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Extension* BackgroundApplicationListModel::GetExtension( 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int position) const { 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(position >= 0 && static_cast<size_t>(position) < extensions_.size()); 240868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return extensions_[position].get(); 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const BackgroundApplicationListModel::Application* 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BackgroundApplicationListModel::FindApplication( 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Extension* extension) const { 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& id = extension->id(); 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ApplicationMap::const_iterator found = applications_.find(id); 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (found == applications_.end()) ? NULL : found->second; 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BackgroundApplicationListModel::Application* 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BackgroundApplicationListModel::FindApplication( 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Extension* extension) { 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& id = extension->id(); 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ApplicationMap::iterator found = applications_.find(id); 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (found == applications_.end()) ? NULL : found->second; 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const gfx::ImageSkia* BackgroundApplicationListModel::GetIcon( 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Extension* extension) { 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Application* application = FindApplication(extension); 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (application) 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return application->icon_.get(); 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AssociateApplicationData(extension); 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int BackgroundApplicationListModel::GetPosition( 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Extension* extension) const { 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int position = 0; 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& id = extension->id(); 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (ExtensionList::const_iterator cursor = extensions_.begin(); 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cursor != extensions_.end(); 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++cursor, ++position) { 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (id == cursor->get()->id()) 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return position; 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return -1; 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 2831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)bool BackgroundApplicationListModel::RequiresBackgroundModeForPushMessaging( 2841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const Extension& extension) { 2851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // No PushMessaging permission - does not require the background mode. 28646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (!extension.permissions_data()->HasAPIPermission( 28746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) APIPermission::kPushMessaging)) { 2881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return false; 28946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 2901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 2911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // If in the whitelist, then does not require background mode even if 2921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // uses push messaging. 2931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // TODO(dimich): remove this whitelist once we have a better way to keep 2941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // listening for GCM. http://crbug.com/311268 2951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) std::string id_hash = base::SHA1HashString(extension.id()); 2961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) std::string hexencoded_id_hash = base::HexEncode(id_hash.c_str(), 2971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) id_hash.length()); 2981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // The id starting from "9A04..." is a one from unit test. 2991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (hexencoded_id_hash == "C41AD9DCD670210295614257EF8C9945AD68D86E" || 3001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) hexencoded_id_hash == "9A0417016F345C934A1A88F55CA17C05014EEEBA") 3011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return false; 3021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return true; 3041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 3051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// static 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BackgroundApplicationListModel::IsBackgroundApp( 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Extension& extension, Profile* profile) { 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // An extension is a "background app" if it has the "background API" 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // permission, and meets one of the following criteria: 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1) It is an extension (not a hosted app). 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 2) It is a hosted app, and has a background contents registered or in the 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // manifest. 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Ephemeral apps are denied any background activity after their event page 3165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // has been destroyed, thus they cannot be background apps. 3175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (extensions::util::IsEphemeralApp(extension.id(), profile)) 3185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return false; 3195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Not a background app if we don't have the background permission or 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the push messaging permission 32246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (!extension.permissions_data()->HasAPIPermission( 32346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) APIPermission::kBackground) && 3241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) !RequiresBackgroundModeForPushMessaging(extension)) 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Extensions and packaged apps with background permission are always treated 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // as background apps. 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!extension.is_hosted_app()) 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Hosted apps with manifest-provided background pages are background apps. 3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (extensions::BackgroundInfo::HasBackgroundPage(&extension)) 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BackgroundContentsService* service = 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BackgroundContentsServiceFactory::GetForProfile(profile); 3385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::string16 app_id = base::ASCIIToUTF16(extension.id()); 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we have an active or registered background contents for this app, then 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // it's a background app. This covers the cases where the app has created its 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // background contents, but it hasn't navigated yet, or the background 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // contents crashed and hasn't yet been restarted - in both cases we still 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // want to treat the app as a background app. 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (service->GetAppBackgroundContents(app_id) || 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) service->HasRegisteredBackgroundContents(app_id)) { 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Doesn't meet our criteria, so it's not a background app. 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BackgroundApplicationListModel::Observe( 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int type, 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::NotificationSource& source, 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::NotificationDetails& details) { 3575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (type == extensions::NOTIFICATION_EXTENSIONS_READY_DEPRECATED) { 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Update(); 359116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ready_ = true; 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ExtensionService* service = extensions::ExtensionSystem::Get(profile_)-> 3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension_service(); 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!service || !service->is_ready()) 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (type) { 3685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case extensions::NOTIFICATION_EXTENSION_LOADED_DEPRECATED: 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnExtensionLoaded(content::Details<Extension>(details).ptr()); 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case extensions::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED: 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnExtensionUnloaded( 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Details<UnloadedExtensionInfo>(details)->extension); 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case extensions::NOTIFICATION_EXTENSION_PERMISSIONS_UPDATED: 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnExtensionPermissionsUpdated( 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Details<UpdatedExtensionPermissionsInfo>(details)->extension, 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Details<UpdatedExtensionPermissionsInfo>(details)->reason, 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Details<UpdatedExtensionPermissionsInfo>(details)-> 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) permissions); 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case chrome::NOTIFICATION_BACKGROUND_CONTENTS_SERVICE_CHANGED: 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Update(); 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Received unexpected notification"; 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BackgroundApplicationListModel::SendApplicationDataChangedNotifications( 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Extension* extension) { 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FOR_EACH_OBSERVER(Observer, observers_, OnApplicationDataChanged(extension, 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile_)); 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BackgroundApplicationListModel::OnExtensionLoaded( 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Extension* extension) { 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We only care about extensions that are background applications 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IsBackgroundApp(*extension, profile_)) 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AssociateApplicationData(extension); 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BackgroundApplicationListModel::OnExtensionUnloaded( 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Extension* extension) { 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IsBackgroundApp(*extension, profile_)) 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Update(); 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DissociateApplicationData(extension); 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BackgroundApplicationListModel::OnExtensionPermissionsUpdated( 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Extension* extension, 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdatedExtensionPermissionsInfo::Reason reason, 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PermissionSet* permissions) { 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (permissions->HasAPIPermission(APIPermission::kBackground)) { 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (reason) { 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case UpdatedExtensionPermissionsInfo::ADDED: 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(IsBackgroundApp(*extension, profile_)); 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnExtensionLoaded(extension); 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case UpdatedExtensionPermissionsInfo::REMOVED: 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!IsBackgroundApp(*extension, profile_)); 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Update(); 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DissociateApplicationData(extension); 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BackgroundApplicationListModel::RemoveObserver(Observer* observer) { 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observers_.RemoveObserver(observer); 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Update queries the extensions service of the profile with which the model was 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// initialized to determine the current set of background applications. If that 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// differs from the old list, it generates OnApplicationListChanged events for 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// each observer. 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BackgroundApplicationListModel::Update() { 4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ExtensionService* service = extensions::ExtensionSystem::Get(profile_)-> 4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension_service(); 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Discover current background applications, compare with previous list, which 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // is consistently sorted, and notify observers if they differ. 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionList extensions; 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetServiceApplications(service, &extensions); 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionList::const_iterator old_cursor = extensions_.begin(); 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionList::const_iterator new_cursor = extensions.begin(); 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (old_cursor != extensions_.end() && 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_cursor != extensions.end() && 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*old_cursor)->name() == (*new_cursor)->name() && 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*old_cursor)->id() == (*new_cursor)->id()) { 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++old_cursor; 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++new_cursor; 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (old_cursor != extensions_.end() || new_cursor != extensions.end()) { 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extensions_ = extensions; 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FOR_EACH_OBSERVER(Observer, observers_, OnApplicationListChanged(profile_)); 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 463