123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208 |
- // Copyright (c) 2013 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #ifndef EXTENSIONS_COMMON_MANIFEST_HANDLER_H_
- #define EXTENSIONS_COMMON_MANIFEST_HANDLER_H_
- #include <memory>
- #include <set>
- #include <string>
- #include <unordered_map>
- #include <vector>
- #include "base/containers/small_map.h"
- #include "base/containers/span.h"
- #include "base/gtest_prod_util.h"
- #include "base/lazy_instance.h"
- #include "extensions/common/manifest.h"
- namespace extensions {
- class Extension;
- class ManifestPermission;
- class ManifestPermissionSet;
- // An interface for clients that recognize and parse keys in extension
- // manifests.
- class ManifestHandler {
- public:
- ManifestHandler();
- ManifestHandler(const ManifestHandler&) = delete;
- ManifestHandler& operator=(const ManifestHandler&) = delete;
- virtual ~ManifestHandler();
- // Attempts to parse the extension's manifest.
- // Returns true on success or false on failure; if false, |error| will
- // be set to a failure message.
- // This does not perform any IO operations.
- virtual bool Parse(Extension* extension, std::u16string* error) = 0;
- // Validate that files associated with this manifest key exist.
- // Validation takes place after parsing. May also append a series of
- // warning messages to |warnings|.
- // This may perform IO operations.
- //
- // Otherwise, returns false, and a description of the error is
- // returned in |error|.
- // TODO(yoz): Change error to std::u16string. See crbug.com/71980.
- virtual bool Validate(const Extension* extension,
- std::string* error,
- std::vector<InstallWarning>* warnings) const;
- // If false (the default), only parse the manifest if a registered
- // key is present in the manifest. If true, always attempt to parse
- // the manifest for this extension type, even if no registered keys
- // are present. This allows specifying a default parsed value for
- // extensions that don't declare our key in the manifest.
- // TODO(yoz): Use Feature availability instead.
- virtual bool AlwaysParseForType(Manifest::Type type) const;
- // Same as AlwaysParseForType, but for Validate instead of Parse.
- virtual bool AlwaysValidateForType(Manifest::Type type) const;
- // The list of keys that, if present, should be parsed before calling our
- // Parse (typically, because our Parse needs to read those keys).
- // Defaults to empty.
- virtual const std::vector<std::string> PrerequisiteKeys() const;
- // Creates a |ManifestPermission| instance for the given manifest key |name|.
- // The returned permission does not contain any permission data, so this
- // method is usually used before calling |FromValue| or |Read|. Returns
- // |NULL| if the manifest handler does not support custom permissions.
- virtual ManifestPermission* CreatePermission();
- // Creates a |ManifestPermission| instance containing the initial set of
- // required manifest permissions for the given |extension|. Returns |NULL| if
- // the manifest handler does not support custom permissions or if there was
- // no manifest key in the extension manifest for this handler.
- virtual ManifestPermission* CreateInitialRequiredPermission(
- const Extension* extension);
- // The keys this handler is responsible for.
- virtual base::span<const char* const> Keys() const = 0;
- // Calling FinalizeRegistration indicates that there are no more
- // manifest handlers to be registered.
- static void FinalizeRegistration();
- static bool IsRegistrationFinalized();
- // Call Parse on all registered manifest handlers that should parse
- // this extension.
- static bool ParseExtension(Extension* extension, std::u16string* error);
- // Call Validate on all registered manifest handlers for this extension. This
- // may perform IO operations.
- static bool ValidateExtension(const Extension* extension,
- std::string* error,
- std::vector<InstallWarning>* warnings);
- // Calls |CreatePermission| on the manifest handler for |key|. Returns |NULL|
- // if there is no manifest handler for |key| or if the manifest handler for
- // |key| does not support custom permissions.
- static ManifestPermission* CreatePermission(const std::string& key);
- // Calls |CreateInitialRequiredPermission| on all registered manifest handlers
- // and adds the returned permissions to |permission_set|. Note this should be
- // called after all manifest data elements have been read, parsed and stored
- // in the manifest data property of |extension|, as manifest handlers need
- // access to their manifest data to initialize their required manifest
- // permission.
- static void AddExtensionInitialRequiredPermissions(
- const Extension* extension, ManifestPermissionSet* permission_set);
- protected:
- // A convenience method for handlers that only register for 1 key,
- // so that they can define keys() { return SingleKey(kKey); }
- static const std::vector<std::string> SingleKey(const std::string& key);
- };
- // The global registry for manifest handlers.
- class ManifestHandlerRegistry {
- public:
- ManifestHandlerRegistry(const ManifestHandlerRegistry&) = delete;
- ManifestHandlerRegistry& operator=(const ManifestHandlerRegistry&) = delete;
- // Get the one true instance.
- static ManifestHandlerRegistry* Get();
- // Registers a ManifestHandler, associating it with its keys. If there is
- // already a handler registered for any key |handler| manages, this method
- // will DCHECK.
- void RegisterHandler(std::unique_ptr<ManifestHandler> handler);
- private:
- friend class ManifestHandler;
- friend class ScopedTestingManifestHandlerRegistry;
- friend struct base::LazyInstanceTraitsBase<ManifestHandlerRegistry>;
- FRIEND_TEST_ALL_PREFIXES(ManifestHandlerPerfTest, MANUAL_CommonInitialize);
- FRIEND_TEST_ALL_PREFIXES(ManifestHandlerPerfTest, MANUAL_LookupTest);
- FRIEND_TEST_ALL_PREFIXES(ManifestHandlerPerfTest,
- MANUAL_CommonMeasureFinalization);
- FRIEND_TEST_ALL_PREFIXES(ChromeExtensionsClientTest,
- CheckManifestHandlerRegistryForOverflow);
- ManifestHandlerRegistry();
- ~ManifestHandlerRegistry();
- void Finalize();
- bool ParseExtension(Extension* extension, std::u16string* error);
- bool ValidateExtension(const Extension* extension,
- std::string* error,
- std::vector<InstallWarning>* warnings);
- ManifestPermission* CreatePermission(const std::string& key);
- void AddExtensionInitialRequiredPermissions(
- const Extension* extension,
- ManifestPermissionSet* permission_set);
- // Reset the one true instance.
- static void ResetForTesting();
- // Overrides the current global ManifestHandlerRegistry with
- // |registry|, returning the current one.
- static ManifestHandlerRegistry* SetForTesting(
- ManifestHandlerRegistry* new_registry);
- // The owned collection of manifest handlers. These are then referenced by
- // raw pointer in maps for keys and priority.
- std::vector<std::unique_ptr<ManifestHandler>> owned_manifest_handlers_;
- // This number is derived from determining the total number of manifest
- // handlers that are installed for all build configurations. It is
- // checked through a unit test:
- // ChromeExtensionsClientTest.CheckManifestHandlerRegistryForOverflow.
- //
- // Any new manifest handlers added may cause the small_map to overflow
- // to the backup std::unordered_map, which we don't want, as that would
- // defeat the optimization of using small_map.
- static constexpr size_t kHandlerMax = 87;
- using FallbackMap = std::unordered_map<std::string, ManifestHandler*>;
- using ManifestHandlerMap = base::small_map<FallbackMap, kHandlerMax>;
- using FallbackPriorityMap = std::unordered_map<ManifestHandler*, int>;
- using ManifestHandlerPriorityMap =
- base::small_map<FallbackPriorityMap, kHandlerMax>;
- // Puts the manifest handlers in order such that each handler comes after
- // any handlers for their PrerequisiteKeys. If there is no handler for
- // a prerequisite key, that dependency is simply ignored.
- // CHECKs that there are no manifest handlers with circular dependencies.
- void SortManifestHandlers();
- // All registered manifest handlers.
- ManifestHandlerMap handlers_;
- // The priority for each manifest handler. Handlers with lower priority
- // values are evaluated first.
- ManifestHandlerPriorityMap priority_map_;
- bool is_finalized_;
- };
- } // namespace extensions
- #endif // EXTENSIONS_COMMON_MANIFEST_HANDLER_H_
|