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) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef CHROME_COMMON_EXTENSIONS_MANIFEST_HANDLER_H_ 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define CHROME_COMMON_EXTENSIONS_MANIFEST_HANDLER_H_ 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <set> 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <string> 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <vector> 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/lazy_instance.h" 13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/memory/linked_ptr.h" 14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string16.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/extensions/manifest.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace extensions { 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class Extension; 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// An interface for clients that recognize and parse keys in extension 21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// manifests. 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ManifestHandler { 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ManifestHandler(); 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~ManifestHandler(); 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Attempts to parse the extension's manifest. 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Returns true on success or false on failure; if false, |error| will 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // be set to a failure message. 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool Parse(Extension* extension, string16* error) = 0; 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Validate that files associated with this manifest key exist. 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Validation takes place after parsing. May also append a series of 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // warning messages to |warnings|. 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Otherwise, returns false, and a description of the error is 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // returned in |error|. 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(yoz): Change error to string16. See crbug.com/71980. 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool Validate(const Extension* extension, 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string* error, 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<InstallWarning>* warnings) const; 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If false (the default), only parse the manifest if a registered 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // key is present in the manifest. If true, always attempt to parse 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the manifest for this extension type, even if no registered keys 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // are present. This allows specifying a default parsed value for 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // extensions that don't declare our key in the manifest. 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(yoz): Use Feature availability instead. 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool AlwaysParseForType(Manifest::Type type) const; 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Same as AlwaysParseForType, but for Validate instead of Parse. 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool AlwaysValidateForType(Manifest::Type type) const; 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The list of keys that, if present, should be parsed before calling our 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Parse (typically, because our Parse needs to read those keys). 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Defaults to empty. 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual const std::vector<std::string> PrerequisiteKeys() const; 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Associate us with our keys() in the manifest. A handler can register 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // for multiple keys. The global registry takes ownership of this; 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // if it has an existing handler for |key|, it replaces it with this. 627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Manifest handlers must be registered at process startup in 637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // chrome_manifest_handlers.cc: 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // (new MyManifestHandler)->Register(); 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void Register(); 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Calling FinalizeRegistration indicates that there are no more 687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // manifest handlers to be registered. 697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch static void FinalizeRegistration(); 707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch static bool IsRegistrationFinalized(); 727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Call Parse on all registered manifest handlers that should parse 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // this extension. 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static bool ParseExtension(Extension* extension, string16* error); 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Call Validate on all registered manifest handlers for this extension. 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static bool ValidateExtension(const Extension* extension, 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string* error, 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<InstallWarning>* warnings); 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected: 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // A convenience method for handlers that only register for 1 key, 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // so that they can define keys() { return SingleKey(kKey); } 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static const std::vector<std::string> SingleKey(const std::string& key); 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The keys to register us for (in Register). 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual const std::vector<std::string> Keys() const = 0; 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// The global registry for manifest handlers. 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class ManifestHandlerRegistry { 94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private: 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) friend class ManifestHandler; 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) friend class ScopedTestingManifestHandlerRegistry; 97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) friend struct base::DefaultLazyInstanceTraits<ManifestHandlerRegistry>; 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ManifestHandlerRegistry(); 100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ~ManifestHandlerRegistry(); 101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch void Finalize(); 1037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void RegisterManifestHandler(const std::string& key, 105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) linked_ptr<ManifestHandler> handler); 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool ParseExtension(Extension* extension, string16* error); 107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool ValidateExtension(const Extension* extension, 108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string* error, 109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::vector<InstallWarning>* warnings); 110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Overrides the current global ManifestHandlerRegistry with 112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // |registry|, returning the current one. 113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) static ManifestHandlerRegistry* SetForTesting( 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ManifestHandlerRegistry* new_registry); 115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) typedef std::map<std::string, linked_ptr<ManifestHandler> > 117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ManifestHandlerMap; 118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) typedef std::map<ManifestHandler*, int> ManifestHandlerPriorityMap; 119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Puts the manifest handlers in order such that each handler comes after 121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // any handlers for their PrerequisiteKeys. If there is no handler for 122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // a prerequisite key, that dependency is simply ignored. 123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // CHECKs that there are no manifest handlers with circular dependencies. 124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void SortManifestHandlers(); 125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // All registered manifest handlers. 127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ManifestHandlerMap handlers_; 128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The priority for each manifest handler. Handlers with lower priority 130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // values are evaluated first. 131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ManifestHandlerPriorityMap priority_map_; 1327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch bool is_finalized_; 134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace extensions 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif // CHROME_COMMON_EXTENSIONS_MANIFEST_HANDLER_H_ 139