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