12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/manifest_handler.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <map> 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/stl_util.h" 11f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.h" 12f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/permissions/manifest_permission.h" 13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/permissions/manifest_permission_set.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace extensions { 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static base::LazyInstance<ManifestHandlerRegistry> g_registry = 20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LAZY_INSTANCE_INITIALIZER; 21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static ManifestHandlerRegistry* g_registry_override = NULL; 22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ManifestHandlerRegistry* GetRegistry() { 24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!g_registry_override) 25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return g_registry.Pointer(); 26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return g_registry_override; 27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace 30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ManifestHandler::ManifestHandler() { 32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ManifestHandler::~ManifestHandler() { 35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool ManifestHandler::Validate(const Extension* extension, 38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string* error, 39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::vector<InstallWarning>* warnings) const { 40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool ManifestHandler::AlwaysParseForType(Manifest::Type type) const { 44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool ManifestHandler::AlwaysValidateForType(Manifest::Type type) const { 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const std::vector<std::string> ManifestHandler::PrerequisiteKeys() const { 52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return std::vector<std::string>(); 53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ManifestHandler::Register() { 56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) linked_ptr<ManifestHandler> this_linked(this); 57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::vector<std::string> keys = Keys(); 58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (size_t i = 0; i < keys.size(); ++i) 59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetRegistry()->RegisterManifestHandler(keys[i], this_linked); 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ManifestPermission* ManifestHandler::CreatePermission() { 63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return NULL; 64f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ManifestPermission* ManifestHandler::CreateInitialRequiredPermission( 67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const Extension* extension) { 68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return NULL; 69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static 727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid ManifestHandler::FinalizeRegistration() { 737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch GetRegistry()->Finalize(); 747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// static 777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochbool ManifestHandler::IsRegistrationFinalized() { 787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return GetRegistry()->is_finalized_; 797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// static 825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool ManifestHandler::ParseExtension(Extension* extension, 835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::string16* error) { 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return GetRegistry()->ParseExtension(extension, error); 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static 88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool ManifestHandler::ValidateExtension(const Extension* extension, 89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string* error, 90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::vector<InstallWarning>* warnings) { 91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return GetRegistry()->ValidateExtension(extension, error, warnings); 92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static 95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ManifestPermission* ManifestHandler::CreatePermission(const std::string& name) { 96f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return GetRegistry()->CreatePermission(name); 97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 99f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// static 100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ManifestHandler::AddExtensionInitialRequiredPermissions( 101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const Extension* extension, ManifestPermissionSet* permission_set) { 102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return GetRegistry()->AddExtensionInitialRequiredPermissions(extension, 103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) permission_set); 104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// static 107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const std::vector<std::string> ManifestHandler::SingleKey( 108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& key) { 109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return std::vector<std::string>(1, key); 110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1127dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochManifestHandlerRegistry::ManifestHandlerRegistry() : is_finalized_(false) { 113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ManifestHandlerRegistry::~ManifestHandlerRegistry() { 116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid ManifestHandlerRegistry::Finalize() { 1197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CHECK(!is_finalized_); 1207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch SortManifestHandlers(); 1217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch is_finalized_ = true; 1227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 1237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ManifestHandlerRegistry::RegisterManifestHandler( 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& key, linked_ptr<ManifestHandler> handler) { 1267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CHECK(!is_finalized_); 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) handlers_[key] = handler; 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ManifestHandlerRegistry::ParseExtension(Extension* extension, 1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::string16* error) { 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::map<int, ManifestHandler*> handlers_by_priority; 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (ManifestHandlerMap::iterator iter = handlers_.begin(); 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter != handlers_.end(); ++iter) { 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ManifestHandler* handler = iter->second.get(); 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (extension->manifest()->HasPath(iter->first) || 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) handler->AlwaysParseForType(extension->GetType())) { 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) handlers_by_priority[priority_map_[handler]] = handler; 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (std::map<int, ManifestHandler*>::iterator iter = 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) handlers_by_priority.begin(); 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter != handlers_by_priority.end(); ++iter) { 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!(iter->second)->Parse(extension, error)) 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ManifestHandlerRegistry::ValidateExtension( 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const Extension* extension, 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string* error, 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<InstallWarning>* warnings) { 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::set<ManifestHandler*> handlers; 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (ManifestHandlerMap::iterator iter = handlers_.begin(); 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter != handlers_.end(); ++iter) { 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ManifestHandler* handler = iter->second.get(); 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (extension->manifest()->HasPath(iter->first) || 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) handler->AlwaysValidateForType(extension->GetType())) { 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) handlers.insert(handler); 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (std::set<ManifestHandler*>::iterator iter = handlers.begin(); 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter != handlers.end(); ++iter) { 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!(*iter)->Validate(extension, error, warnings)) 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 171f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ManifestPermission* ManifestHandlerRegistry::CreatePermission( 172f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const std::string& name) { 173f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ManifestHandlerMap::const_iterator it = handlers_.find(name); 174f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (it == handlers_.end()) 175f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return NULL; 176f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 177f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return it->second->CreatePermission(); 178f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 179f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 180f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ManifestHandlerRegistry::AddExtensionInitialRequiredPermissions( 181f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const Extension* extension, ManifestPermissionSet* permission_set) { 182f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (ManifestHandlerMap::const_iterator it = handlers_.begin(); 183f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) it != handlers_.end(); ++it) { 184f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ManifestPermission* permission = 185f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) it->second->CreateInitialRequiredPermission(extension); 186f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (permission) { 187f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) permission_set->insert(permission); 188f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 189f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 190f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 191f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static 193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ManifestHandlerRegistry* ManifestHandlerRegistry::SetForTesting( 194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ManifestHandlerRegistry* new_registry) { 195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ManifestHandlerRegistry* old_registry = GetRegistry(); 196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (new_registry != g_registry.Pointer()) 197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) g_registry_override = new_registry; 198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) else 199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) g_registry_override = NULL; 200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return old_registry; 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ManifestHandlerRegistry::SortManifestHandlers() { 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::set<ManifestHandler*> unsorted_handlers; 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (ManifestHandlerMap::const_iterator iter = handlers_.begin(); 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter != handlers_.end(); ++iter) { 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsorted_handlers.insert(iter->second.get()); 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int priority = 0; 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) while (true) { 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::set<ManifestHandler*> next_unsorted_handlers; 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (std::set<ManifestHandler*>::const_iterator iter = 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsorted_handlers.begin(); 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter != unsorted_handlers.end(); ++iter) { 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ManifestHandler* handler = *iter; 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::vector<std::string>& prerequisites = 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) handler->PrerequisiteKeys(); 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int unsatisfied = prerequisites.size(); 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < prerequisites.size(); ++i) { 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ManifestHandlerMap::const_iterator prereq_iter = 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) handlers_.find(prerequisites[i]); 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If the prerequisite does not exist, crash. 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK(prereq_iter != handlers_.end()) 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << "Extension manifest handler depends on unrecognized key " 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << prerequisites[i]; 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Prerequisite is in our map. 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (ContainsKey(priority_map_, prereq_iter->second.get())) 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsatisfied--; 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (unsatisfied == 0) { 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) priority_map_[handler] = priority; 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) priority++; 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Put in the list for next time. 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) next_unsorted_handlers.insert(handler); 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (next_unsorted_handlers.size() == unsorted_handlers.size()) 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsorted_handlers.swap(next_unsorted_handlers); 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If there are any leftover unsorted handlers, they must have had 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // circular dependencies. 246cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CHECK_EQ(unsorted_handlers.size(), std::set<ManifestHandler*>::size_type(0)) 247cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) << "Extension manifest handlers have circular dependencies!"; 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace extensions 251